home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-10 | 96.6 KB | 3,430 lines |
- diff -u -r --new-file last-version/source/Makefile samba-1.9.14p4/source/Makefile
- --- last-version/source/Makefile Tue Nov 7 22:58:21 1995
- +++ samba-1.9.14p4/source/Makefile Fri Nov 10 18:50:20 1995
- @@ -85,10 +85,12 @@
- # DCE_LIBS =
-
- # This is for SMB encrypted (lanman) passwords.
- +# you may wish to add -DREPLACE_GETPASS if your getpass() is limited
- +# to 8 chars
- # DES_BASE=/usr/local/libdes
- # DES_FLAGS= -I$(DES_BASE)
- # DES_LIB= -L$(DES_BASE) -ldes
- -# PASSWD_FLAGS=-DSMB_PASSWD -DSMBGETPASS -DSMB_PASSWD_FILE=\"$(BASEDIR)/private/smbpasswd\"
- +# PASSWD_FLAGS=-DSMB_PASSWD -DSMB_PASSWD_FILE=\"$(BASEDIR)/private/smbpasswd\"
-
- ######################################
- # VTP-Support
- @@ -353,7 +355,7 @@
- # contributed by cjkiick@flinx.b11.ingr.com
- # modified by ttj@sknsws61.sjo.statkart.no
- # FLAGSM = -DCLIX -D_INGR_EXTENSIONS=1
- -# LIBSM = -lbsd
- +# LIBSM = -lbsd -lc_s
-
- # This is for DGUX.
- # Contributed by ross@augie.insci.com (Ross Andrus)
- @@ -423,7 +425,7 @@
- LIBS = $(LIBS1) $(LIBSM) $(DCE_LIBS) $(DES_LIB)
-
- PROGS1 = smbd smbclient nmbd testparm testprns smbrun smbstatus smbpasswd
- -PROGS = $(PROGS1) nmbd2
- +PROGS = $(PROGS1) nmbd2 nmblookup
- SCRIPTS = smbtar
-
- all : CHECK $(PROGS)
- @@ -464,13 +466,17 @@
- @echo Linking nmbd
- @$(CC) $(CFLAGS) -o nmbd nameserv.o $(UTILOBJ) $(LIBS)
-
- +nmblookup: nmblookup.o $(UTILOBJ)
- + @echo Linking nmblookup
- + @$(CC) $(CFLAGS) -o nmblookup nmblookup.o nmblib.o $(UTILOBJ) $(LIBS)
- +
- nmbd2: nameserv2.o nmblib.o $(UTILOBJ)
- @echo Linking nmbd2
- @$(CC) $(CFLAGS) -o nmbd2 nameserv2.o nmblib.o $(UTILOBJ) $(LIBS)
-
- -smbclient: client.o clitar.o $(UTILOBJ)
- +smbclient: client.o clitar.o getsmbpass.o $(UTILOBJ)
- @echo Linking smbclient
- - @$(CC) $(CFLAGS) -o smbclient client.o clitar.o $(UTILOBJ) $(LIBS)
- + @$(CC) $(CFLAGS) -o smbclient client.o clitar.o getsmbpass.o $(UTILOBJ) $(LIBS)
-
- smbstatus: status.o $(PARAMOBJ)
- @echo Linking smbstatus
- @@ -486,7 +492,7 @@
-
- smbpasswd: smbpasswd.o getsmbpass.o $(PARAMOBJ)
- @echo Linking smbpasswd
- - @$(CC) $(CFLAGS) -o smbpasswd getsmbpass.o smbpasswd.o $(PARAMOBJ) $(LIBS)
- + @$(CC) $(CFLAGS) -o smbpasswd smbpasswd.o getsmbpass.o $(PARAMOBJ) $(LIBS)
-
- install: installbin installman
-
- diff -u -r --new-file last-version/source/change-log samba-1.9.14p4/source/change-log
- --- last-version/source/change-log Tue Nov 7 22:59:06 1995
- +++ samba-1.9.14p4/source/change-log Fri Nov 10 22:55:26 1995
- @@ -1628,7 +1628,16 @@
- - is08859-1 patches from eauth@mail.cso.co.at
- - starting rewriting nmbd, new nmbd is nmbd2, old one still around
- for time being
- + - released p3
- + - rewrote more of nmbd2 to use new structures
- + - CLIX patches from Jason.J.Faultless@bechtel.btx400.co.uk
- + - DirCacheFlush() bugfix from Michael Joosten
- + <joost@ori.cadlab.de>. This bug explains a lot of the crashes.
- + - fixed a bug in ChDir() that caused reversion to / in some
- + situations
- + - ipc fix from Magnus Hyllander <mhy@os.se>
-
- +
- ==========
- todo:
-
- @@ -1639,8 +1648,6 @@
-
- add masking to opendir?
-
- -rename only if not rdonly?
- -
- no refresh/reg of new IP? or send wack and challenge owner?
-
- new nmb.conf file
- @@ -1667,12 +1674,9 @@
-
- apparently WfWg doesn't like the password server stuff in 1.9.14. Why?
-
- -UNRESOLVED PROBLEMS
- -===================
- +add "hide file = *.o" "hide dir = .Foo*" "show file = xx*" type options.
-
- ----
- ALLOW_PASSWORD_CHANGE only compiles/works on some systems
-
- ----
- weird foooooooo/open.exe bug on NT
-
- diff -u -r --new-file last-version/source/client.c samba-1.9.14p4/source/client.c
- --- last-version/source/client.c Tue Nov 7 13:59:55 1995
- +++ samba-1.9.14p4/source/client.c Fri Nov 10 18:24:34 1995
- @@ -45,7 +45,7 @@
- #define CLIENT_TIMEOUT (30*1000)
- #define SHORT_TIMEOUT (5*1000)
-
- -int name_type = ' ';
- +int name_type = 0x20;
- int max_protocol = PROTOCOL_NT1;
-
-
- @@ -2749,7 +2749,7 @@
- putip((char *)&dest_ip,inbuf+4);
-
- close_sockets();
- - Client = open_socket_out(&dest_ip, port);
- + Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
- if (Client == -1)
- return False;
-
- @@ -2971,7 +2971,7 @@
- strcpy(pword,pass);
-
- #ifdef SMB_PASSWD
- - if (doencrypt) {
- + if (doencrypt && *pass) {
- DEBUG(3,("Using encrypted passwords\n"));
- passlen = 24;
- SMBencrypt(pass,cryptkey,pword);
- @@ -3090,7 +3090,7 @@
- strcpy(pword,pass);
-
- #ifdef SMB_PASSWD
- - if (doencrypt) {
- + if (doencrypt && *pass) {
- passlen=24;
- SMBencrypt(pass,cryptkey,pword);
- }
- @@ -3577,7 +3577,7 @@
- putip((char *)&dest_ip,(char *)hp->h_addr);
- }
-
- - Client = open_socket_out(&dest_ip, port);
- + Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
- if (Client == -1)
- return False;
-
- @@ -3931,9 +3931,8 @@
- break;
- case 'I':
- {
- - unsigned long a = interpret_addr(optarg);
- - if (!a) exit(1);
- - putip((char *)&dest_ip,(char *)&a);
- + dest_ip = *interpret_addr2(optarg);
- + if (zero_ip(dest_ip)) exit(1);
- have_ip = True;
- }
- break;
- diff -u -r --new-file last-version/source/dir.c samba-1.9.14p4/source/dir.c
- --- last-version/source/dir.c Tue Nov 7 12:46:56 1995
- +++ samba-1.9.14p4/source/dir.c Fri Nov 10 11:18:03 1995
- @@ -671,6 +671,7 @@
- next = entry->next;
- if (entry->prev) entry->prev->next = entry->next;
- if (entry->next) entry->next->prev = entry->prev;
- + if (dir_cache == entry) dir_cache = entry->next;
- free(entry);
- } else {
- next = entry->next;
- diff -u -r --new-file last-version/source/getsmbpass.c samba-1.9.14p4/source/getsmbpass.c
- --- last-version/source/getsmbpass.c Thu Sep 14 12:25:43 1995
- +++ samba-1.9.14p4/source/getsmbpass.c Fri Nov 10 10:42:50 1995
- @@ -1,5 +1,3 @@
- -#if (defined(SMB_PASSWD) && defined(SMBGETPASS))
- -
- /* Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- @@ -29,6 +27,9 @@
- #endif
-
- #include "includes.h"
- +
- +#ifdef REPLACE_GETPASS
- +
-
- #include <termios.h>
-
- diff -u -r --new-file last-version/source/includes.h samba-1.9.14p4/source/includes.h
- --- last-version/source/includes.h Tue Nov 7 12:49:21 1995
- +++ samba-1.9.14p4/source/includes.h Fri Nov 10 10:47:02 1995
- @@ -226,6 +226,7 @@
- #include <utime.h>
- #define NO_STRERROR
- #endif
- +#define REPLACE_GETPASS
- #endif
-
-
- @@ -257,6 +258,7 @@
- #define USE_STATVFS
- #define USE_GETCWD
- #define USE_SETSID
- +#define REPLACE_GETPASS
- #endif
-
-
- @@ -396,6 +398,8 @@
- #define NO_FSYNC
- #define USE_GETCWD
- #define USE_SETSID
- +#define REPLACE_GETPASS
- +#define NO_GETRLIMIT
- #endif /* CLIX */
-
-
- @@ -753,6 +757,12 @@
- /*******************************************************************
- end of the platform specific sections
- ********************************************************************/
- +
- +#ifdef REPLACE_GETPASS
- +extern char *getsmbpass(char *);
- +#define getpass(s) getsmbpass(s)
- +#endif
- +
-
- #ifndef MAXINT
- #define MAXINT ((((unsigned)1)<<(sizeof(int)*8-1))-1)
- diff -u -r --new-file last-version/source/ipc.c samba-1.9.14p4/source/ipc.c
- --- last-version/source/ipc.c Mon Nov 6 16:54:58 1995
- +++ samba-1.9.14p4/source/ipc.c Fri Nov 10 22:51:57 1995
- @@ -572,7 +572,7 @@
- char *p = skip_string(str2,1);
- char *QueueName = p;
- int uLevel,cbBuf;
- - int count;
- + int count=0;
- int snum;
- char* str3;
- struct pack_desc desc;
- @@ -604,6 +604,8 @@
- }
- }
-
- + if (snum < 0 || !VALID_SNUM(snum)) return(False);
- +
- count = get_printqueue(snum,cnum,&queue,&status);
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- @@ -1041,7 +1043,7 @@
-
- SSVAL(*rparam,0,NERR_Success);
-
- - if (snum >= 0)
- + if (snum >= 0 && VALID_SNUM(snum))
- {
- print_queue_struct *queue=NULL;
- lpq_reset(snum);
- @@ -1108,7 +1110,7 @@
- }
- }
-
- - if (snum >= 0) {
- + if (snum >= 0 && VALID_SNUM(snum)) {
- print_queue_struct *queue=NULL;
- int i, count;
- lpq_reset(snum);
- @@ -1176,7 +1178,7 @@
-
- switch (function) {
- case 0x6: /* change job place in the queue, data gives the new place */
- - if (snum >= 0)
- + if (snum >= 0 && VALID_SNUM(snum))
- {
- print_queue_struct *queue=NULL;
- int count;
- @@ -1672,6 +1674,8 @@
- snum = (unsigned int)uJobId >> 8; /*## valid serice number??*/
- job = uJobId & 0xFF;
-
- + if (snum < 0 || !VALID_SNUM(snum)) return(False);
- +
- count = get_printqueue(snum,cnum,&queue,&status);
- for (i = 0; i < count; i++) {
- if ((queue[i].job % 0xFF) == job) break;
- @@ -1742,6 +1746,8 @@
- snum = lp_servicenumber(name);
- }
- }
- +
- + if (snum < 0 || !VALID_SNUM(snum)) return(False);
-
- count = get_printqueue(snum,cnum,&queue,&status);
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- diff -u -r --new-file last-version/source/local.h samba-1.9.14p4/source/local.h
- --- last-version/source/local.h Sun Nov 5 12:37:52 1995
- +++ samba-1.9.14p4/source/local.h Fri Nov 10 21:20:57 1995
- @@ -118,7 +118,6 @@
- #define DPTR_IDLE_TIMEOUT (300)
- #define SMBD_SELECT_LOOP (10)
- #define NMBD_SELECT_LOOP (10)
- -#define BROWSE_INTERVAL (60)
- #define REGISTRATION_INTERVAL (10*60)
- #define NMBD_INETD_TIMEOUT (120)
- #define NMBD_MAX_TTL (24*60*60)
- diff -u -r --new-file last-version/source/nameserv.h samba-1.9.14p4/source/nameserv.h
- --- last-version/source/nameserv.h Tue Nov 7 22:17:38 1995
- +++ samba-1.9.14p4/source/nameserv.h Fri Nov 10 19:08:49 1995
- @@ -26,6 +26,10 @@
- #define NMB_PORT 137
- #define DGRAM_PORT 138
-
- +enum name_source {LMHOSTS, REGISTER, SELF, DNS};
- +enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
- +enum packet_type {NMB_PACKET, DGRAM_PACKET};
- +
- /* a netbios name structure */
- struct nmb_name {
- char name[17];
- @@ -33,6 +37,29 @@
- int name_type;
- };
-
- +/* this is the structure used for the local netbios name list */
- +struct name_record
- +{
- + struct name_record *next;
- + struct name_record *prev;
- + struct nmb_name name;
- + time_t death_time;
- + struct in_addr ip;
- + BOOL unique;
- + enum name_source source;
- +};
- +
- +/* this is used by the list of domains */
- +struct domain_record
- +{
- + struct domain_record *next;
- + struct domain_record *prev;
- + fstring name;
- + time_t lastannounce_time;
- + int announce_interval;
- + struct in_addr bcast_ip;
- +};
- +
- /* a resource record */
- struct res_rec {
- struct nmb_name rr_name;
- @@ -76,25 +103,27 @@
- };
-
-
- -/* a datagram - a simple structure at first, it would be good to parse
- - it properly later */
- +/* a datagram - this normally contains SMB data in the data[] array */
- struct dgram_packet {
- struct {
- - int res;
- - int id;
- - struct in_addr ip;
- - int port;
- - int length;
- - int res2;
- - struct nmb_name source_name;
- - struct nmb_name dest_name;
- + int msg_type;
- + struct {
- + enum node_type node_type;
- + BOOL first;
- + BOOL more;
- + } flags;
- + int dgm_id;
- + struct in_addr source_ip;
- + int source_port;
- + int dgm_length;
- + int packet_offset;
- } header;
- - int smbsize;
- - char smb_data[MAX_DGRAM_SIZE];
- + struct nmb_name source_name;
- + struct nmb_name dest_name;
- + int datasize;
- + char data[MAX_DGRAM_SIZE];
- };
-
- -enum packet_type {NMB_PACKET, DGRAM_PACKET};
- -
- /* define a structure used to queue packets. this will be a linked
- list of nmb packets */
- struct packet_struct
- @@ -128,3 +157,16 @@
- struct packet_struct *read_packet(int fd,enum packet_type packet_type);
- BOOL send_packet(struct packet_struct *p);
- struct packet_struct *receive_packet(int fd,enum packet_type type,int timeout);
- +void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
- +BOOL name_query(int fd,char *name,int name_type,
- + BOOL bcast,BOOL recurse,
- + struct in_addr to_ip, struct in_addr *ip,void (*fn)());
- +BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
- + struct in_addr to_ip,char *master,void (*fn)());
- +BOOL send_udp_dgram(int fd,char *buf,int len,
- + char *srcname,char *dstname,
- + int src_type,int dest_type,
- + struct in_addr dest_ip,
- + struct in_addr src_ip);
- +
- +
- diff -u -r --new-file last-version/source/nameserv2.c samba-1.9.14p4/source/nameserv2.c
- --- last-version/source/nameserv2.c Tue Nov 7 22:37:02 1995
- +++ samba-1.9.14p4/source/nameserv2.c Fri Nov 10 21:20:49 1995
- @@ -25,75 +25,38 @@
-
-
- static void queue_packet(struct packet_struct *packet);
- -
- +void process(void);
- +static void dump_names(void);
-
- extern int DEBUGLEVEL;
-
- -/* the list of network interfaces */
- -struct net_interface *interfaces = NULL;
- -
- extern pstring debugf;
- -extern int DEBUGLEVEL;
-
- extern pstring scope;
-
- -static int browse_interval = BROWSE_INTERVAL;
- -
- -static BOOL dns_serve = False;
- -static BOOL CanRecurse = True;
- +extern BOOL CanRecurse;
-
- -extern struct in_addr lastip;
- -extern int lastport;
- extern struct in_addr myip;
- extern struct in_addr bcast_ip;
- extern struct in_addr Netmask;
- extern pstring myhostname;
- static pstring host_file;
- static pstring myname="";
- -static pstring lookup="";
- +
- static int ClientNMB=-1;
- static int ClientDGRAM=-1;
- -enum name_sources {LMHOSTS, REGISTER, SELF, DNS};
- -
- -/* this is the structure used for the local netbios name table */
- -typedef struct
- -{
- - time_t start_time;
- - int ttl;
- - struct in_addr ip;
- - struct in_addr master_ip;
- - BOOL found_master;
- - BOOL valid;
- - BOOL isgroup;
- - BOOL unicast;
- - char name[100];
- - int type;
- - int count;
- - enum name_sources source;
- -} name_struct;
- -
- -
- -static int num_names=0;
- -static name_struct *names = NULL;
- -
- -#define NAMEVALID(i) names[i].valid
- -#define ISGROUP(i) (names[i].isgroup)
-
- -void process(void);
- +static struct name_record *namelist = NULL;
- +static struct domain_record *domainlist = NULL;
-
- /* are we running as a daemon ? */
- static BOOL is_daemon = False;
-
- -/* machine comment */
- +/* machine comment for host announcements */
- static pstring comment="";
-
- extern pstring user_socket_options;
-
- -static void add_group_name(char *name);
- -static void add_host_name(char *name,int type,struct in_addr *ip);
- -static void dump_names(void);
- -
- -
- static BOOL got_bcast = False;
- static BOOL got_myip = False;
- static BOOL got_nmask = False;
- @@ -150,680 +113,323 @@
- /****************************************************************************
- true if two netbios names are equal
- ****************************************************************************/
- -static BOOL name_equal(char *s1,char *s2,int type1,int type2)
- +static BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
- {
- - char n1[20],n2[20];
- -
- - if (type1 != type2) return(False);
- -
- - StrnCpy(n1,s1,15);
- - StrnCpy(n2,s2,15);
- -
- - trim_string(n1,NULL," ");
- - trim_string(n2,NULL," ");
- + if (n1->name_type != n2->name_type) return(False);
-
- - return(strequal(n1,n2));
- + return(strequal(n1->name,n2->name) && strequal(n1->scope,n2->scope));
- }
-
- /****************************************************************************
- -add a netbios name
- -****************************************************************************/
- -static int add_name(void)
- + add a netbios name into the namelist
- + **************************************************************************/
- +static void add_name(struct name_record *n)
- {
- - int i;
- -
- - for (i=0;i<num_names;i++)
- - if (!names[i].valid)
- - break;
- + struct name_record *n2;
-
- - if (i==num_names) {
- - name_struct *n;
- - if (num_names == 0)
- - n = (name_struct *)malloc(sizeof(name_struct));
- - else
- - n = (name_struct *)realloc(names,sizeof(name_struct)*(num_names+1));
- - if (!n) {
- - DEBUG(0,("Can't malloc more names space!\n"));
- - return(-1);
- - }
- - i = num_names;
- - num_names++;
- - names = n;
- + if (!namelist) {
- + namelist = n;
- + n->prev = NULL;
- + n->next = NULL;
- + return;
- }
-
- - bzero(&names[i],sizeof(names[i]));
- -
- - return(i);
- -}
- -
- -/****************************************************************************
- -find a name
- -****************************************************************************/
- -static int find_name(char *s,int type,BOOL groups)
- -{
- - int i;
- - time_t t = time(NULL);
- + for (n2 = namelist; n2->next; n2 = n2->next) ;
-
- - for (i=0;i<num_names;i++)
- - if (names[i].valid && (groups || !ISGROUP(i)))
- - {
- - if ((names[i].ttl > 0) && (t > (names[i].start_time + names[i].ttl)))
- - names[i].valid = False;
- - else
- - {
- - if (name_equal(s,names[i].name,type,names[i].type)) {
- - return(i);
- - }
- - }
- - }
- - return -1;
- + n2->next = n;
- + n->next = NULL;
- + n->prev = n2;
- }
-
- -
- /****************************************************************************
- -check names, and change any 0 IPs to myip
- -****************************************************************************/
- -static void check_names(void)
- + add a domain into the list
- + **************************************************************************/
- +static void add_domain(struct domain_record *d)
- {
- - int i;
- - int group_count=0;
- -
- - /* add the magic __SAMBA__ name */
- - add_host_name("__SAMBA__",0x20,&myip);
- - add_host_name("__SAMBA__",0x0,&myip);
- -
- - for (i=0;i<num_names;i++)
- - if (names[i].valid) {
- - if (ISGROUP(i)) group_count++;
- - }
- + struct domain_record *d2;
-
- - if (group_count == 0)
- - add_group_name(WORKGROUP);
- + if (!domainlist) {
- + domainlist = d;
- + d->prev = NULL;
- + d->next = NULL;
- + return;
- + }
-
- + for (d2 = domainlist; d2->next; d2 = d2->next) ;
-
- - for (i=0;i<num_names;i++)
- - if (names[i].valid && strequal((char *)inet_ntoa(names[i].ip),"0.0.0.0"))
- - names[i].ip = (ISGROUP(i)?bcast_ip:myip);
- + d2->next = d;
- + d->next = NULL;
- + d->prev = d2;
- }
-
- -
- /****************************************************************************
- -dump a copy of the name table
- -****************************************************************************/
- -static void dump_names(void)
- + remove a name from the namelist. The pointer must be an element just
- + retrieved
- + **************************************************************************/
- +static void remove_name(struct name_record *n)
- {
- - int i;
- - DEBUG(3,("Dump of local name table\n"));
- - for (i=0;i<num_names;i++)
- - if (names[i].valid) {
- - DEBUG(3,("%s %s %d %s",
- - names[i].name,inet_ntoa(names[i].ip),
- - names[i].ttl,BOOLSTR(names[i].isgroup)));
- - if (names[i].found_master)
- - DEBUG(3,(" %s",inet_ntoa(names[i].master_ip)));
- - DEBUG(3,("\n"));
- - }
- + struct name_record *nlist = namelist;
- + while (nlist && nlist != n) nlist = nlist->next;
- + if (nlist) {
- + if (nlist->next) nlist->next->prev = nlist->prev;
- + if (nlist->prev) nlist->prev->next = nlist->next;
- + free(nlist);
- + }
- }
-
- -
- /****************************************************************************
- -load a netbios hosts file
- -****************************************************************************/
- -static void load_hosts_file(char *fname)
- + find a name in the namelist matching some criterion
- + **************************************************************************/
- +static struct name_record *find_name(struct nmb_name *n)
- {
- - int i;
- - FILE *f = fopen(fname,"r");
- - pstring line;
- - if (!f)
- - {
- - DEBUG(2,("Not using non-existant lmhosts file %s\n",fname));
- - return;
- - }
- -
- - while (!feof(f))
- - {
- - if (!fgets_slash(line,sizeof(pstring),f)) continue;
- -
- - if (*line == '#') continue;
- -
- - {
- - string ip="",name="",flags="",extra="";
- - unsigned long a;
- - char *ptr;
- - int count = 0;
- - ptr = line;
- - if (next_token(&ptr,ip,NULL)) ++count;
- - if (next_token(&ptr,name,NULL)) ++count;
- - if (next_token(&ptr,flags,NULL)) ++count;
- - if (next_token(&ptr,extra,NULL)) ++count;
- -
- - if (count <= 0) continue;
- -
- - if (count > 0 && count < 2)
- - {
- - DEBUG(0,("Ill formed hosts line [%s]\n",line));
- - continue;
- - }
- + struct name_record *ret;
- + for (ret = namelist; ret; ret = ret->next)
- + if (name_equal(&ret->name,n)) return(ret);
-
- - i = add_name();
- - if (i < 0)
- - {
- - fclose(f);
- - return;
- - }
- + return(NULL);
- +}
-
- - a = interpret_addr(ip);
- - putip((char *)&names[i].ip,(char *)&a);
- +/****************************************************************************
- + dump a copy of the name table
- + **************************************************************************/
- +static void dump_names(void)
- +{
- + time_t t = time(NULL);
- + struct name_record *n;
- + struct domain_record *d;
-
- - names[i].valid = True;
- - names[i].source = LMHOSTS;
- + DEBUG(3,("Dump of local name table:\n"));
-
- - StrnCpy(names[i].name,name,15);
- - if (strchr(flags,'G') || strchr(flags,'S'))
- - names[i].isgroup = True;
- - if (strchr(flags,'M') && !ISGROUP(i))
- - strcpy(myname,name);
- - if (strchr(flags,'U'))
- - names[i].unicast = True;
- - if (names[i].isgroup)
- - names[i].type = 0xF0; /* hopefully invalid */
- - else
- - names[i].type = 0x20;
- - }
- + for (n = namelist; n; n = n->next) {
- + DEBUG(3,("%s(%x) %s TTL=%d Unique=%s\n",
- + n->name.name,n->name.name_type,
- + inet_ntoa(n->ip),
- + n->death_time?n->death_time-t:0,
- + BOOLSTR(n->unique)));
- }
-
- - fclose(f);
- + DEBUG(3,("\nDump of domain list:\n"));
- + for (d = domainlist; d; d = d->next)
- + DEBUG(3,("%s %s\n",d->name,inet_ntoa(d->bcast_ip)));
- }
-
-
- /****************************************************************************
- -add a netbios group name
- -****************************************************************************/
- -static void add_group_name(char *name)
- + add a permanent host entry to the name list
- + ****************************************************************************/
- +static struct name_record *add_host_entry(char *name,int type,BOOL unique,int ttl,
- + enum name_source source,
- + struct in_addr ip)
- {
- - int i = add_name();
- - if (i < 0)
- - return;
- + struct name_record *n = (struct name_record *)malloc(sizeof(*n));
- + struct name_record *n2=NULL;
-
- - bzero((char *)&names[i].ip,sizeof(names[i].ip));
- + if (!n) return(NULL);
-
- - strcpy(names[i].name,name);
- - names[i].isgroup = True;
- - names[i].valid = True;
- - names[i].type = 0xF0;
- - names[i].source = SELF;
- -}
- + bzero((char *)n,sizeof(*n));
-
- -/****************************************************************************
- -add a host name
- -****************************************************************************/
- -static void add_host_name(char *name,int type,struct in_addr *ip)
- -{
- - int i;
- + make_nmb_name(&n->name,name,type,scope);
- + if ((n2=find_name(&n->name))) {
- + free(n);
- + n = n2;
- + }
-
- - if (find_name(name,type,True) >= 0) return;
- + if (ttl) n->death_time = time(NULL)+ttl;
- + n->ip = ip;
- + n->unique = unique;
- + n->source = source;
- +
- + if (!n2) add_name(n);
-
- - i = add_name();
- - if (i < 0)
- - return;
- + DEBUG(3,("Added host entry %s(%x) at %s ttl=%d unique=%s\n",
- + name,type,inet_ntoa(ip),ttl,BOOLSTR(unique)));
-
- - names[i].ip = *ip;
- - strcpy(names[i].name,name);
- - names[i].valid = True;
- - names[i].start_time = time(NULL);
- - names[i].ttl = 0;
- - names[i].type = type;
- - names[i].source = SELF;
- + return(n);
- }
-
- +
- /****************************************************************************
- -work out the length of a nmb message
- -****************************************************************************/
- -static int nmb_len(char *buf)
- + add a domain entry
- + ****************************************************************************/
- +static struct domain_record *add_domain_entry(char *name,struct in_addr ip)
- {
- -int i;
- -int ret = 12;
- -char *p = buf;
- -int qdcount = RSVAL(buf,4);
- -int ancount = RSVAL(buf,6);
- -int nscount = RSVAL(buf,8);
- -int arcount = RSVAL(buf,10);
- -
- -/* check for insane qdcount values? */
- -if (qdcount > 100 || qdcount < 0)
- - {
- - DEBUG(6,("Invalid qdcount? qdcount=%d\n",qdcount));
- - return(0);
- - }
- -
- -for (i=0;i<qdcount;i++)
- - {
- - p = buf + ret;
- - ret += name_len(p) + 4;
- - }
- -
- -for (i=0;i<(ancount + nscount + arcount);i++)
- - {
- - int rdlength;
- - p = buf + ret;
- - ret += name_len(p) + 8;
- - p = buf + ret;
- - rdlength = RSVAL(p,0);
- - ret += rdlength + 2;
- - }
- + struct domain_record *d = (struct domain_record *)malloc(sizeof(*d));
-
- -return(ret);
- -}
- + if (!d) return(NULL);
-
- -/****************************************************************************
- -receive a name message. timeout is in milliseconds
- -****************************************************************************/
- -static int receive_nmb(char *buffer,int timeout)
- -{
- - int ret = read_max_udp(ClientNMB,buffer,sizeof(pstring),timeout);
- + bzero((char *)d,sizeof(*d));
-
- - if (ret < 0)
- - {
- - DEBUG(0,("No bytes from client\n"));
- - if (!is_daemon)
- - {
- - close_sockets();
- - exit(0);
- - }
- - }
- + StrnCpy(d->name,name,sizeof(d->name)-1);
- + d->bcast_ip = ip;
-
- - if (ret <= 1)
- - return 0;
- + add_domain(d);
-
- - log_in(buffer,ret);
- + ip = *interpret_addr2("255.255.255.255");
- + if (name[0] != '*') add_host_entry(name,0x1e,False,0,SELF,ip);
-
- - DEBUG(3,("received packet from (%s) nmb_len=%d len=%d\n",
- - inet_ntoa(lastip),nmb_len(buffer),ret));
- + DEBUG(3,("Added domain entry %s at %s\n",
- + name,inet_ntoa(ip)));
-
- - return(ret);
- + return(d);
- }
-
- +
- /****************************************************************************
- -send a name message
- -****************************************************************************/
- -static BOOL send_nmb(char *buf, int len, struct in_addr *ip,int port)
- + add the magic samba names, useful for finding samba servers
- + **************************************************************************/
- +static void add_my_names(void)
- {
- - BOOL ret;
- - struct sockaddr_in sock_out;
- + struct in_addr ip = *interpret_addr2("0.0.0.0");
-
- - /* set the address and port */
- - bzero((char *)&sock_out,sizeof(sock_out));
- - putip((char *)&sock_out.sin_addr,(char *)ip);
- - sock_out.sin_port = htons( port );
- - sock_out.sin_family = AF_INET;
- -
- - /* log the packet */
- - log_out(buf,len);
- -
- - if (DEBUGLEVEL > 0)
- - DEBUG(3,("sending a packet of len %d to (%s) on port 137 of type DGRAM\n",
- - len,inet_ntoa(*ip)));
- -
- - /* send it */
- - ret = (sendto(ClientNMB,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
- -
- - if (!ret)
- - DEBUG(0,("Send packet failed. ERRNO=%d\n",errno));
- -
- - return(ret);
- + add_host_entry("__SAMBA__",0x20,True,0,SELF,ip);
- + add_host_entry("__SAMBA__",0x0,True,0,SELF,ip);
- + add_host_entry(myname,0x20,True,0,SELF,ip);
- + add_host_entry(myname,0x0,True,0,SELF,ip);
- + add_host_entry(myname,0x3,True,0,SELF,ip);
- + if (!domainlist)
- + add_domain_entry(WORKGROUP,bcast_ip);
- }
-
- -/*******************************************************************
- -check if an IP is on my net
- -********************************************************************/
- -static BOOL is_mynet(struct in_addr ip)
- -{
- - unsigned int net1,net2,nmask,subnet1,subnet2;
- -
- - nmask = *(unsigned int *)&Netmask;
- - net1 = (*(unsigned int *)&myip);
- - subnet1 = net1 & nmask;
- - net2 = (*(unsigned int *)&ip);
- - subnet2 = net2 & nmask;
- -
- - return((net1 != net2) && (subnet1 == subnet2));
- -}
-
- -/****************************************************************************
- -interpret a node status response
- -****************************************************************************/
- -static void interpret_node_status(char *inbuf, char *master)
- +/*******************************************************************
- + delete old names from the namelist
- + ******************************************************************/
- +static void housekeeping(void)
- {
- - int level = master?3:0;
- - char *p = inbuf + 12 + name_len(inbuf+12) + 10;
- - int numnames = CVAL(p,0);
- - DEBUG(level,("received %d names\n",numnames));
- + time_t lastrun=0;
- + time_t t = time(NULL);
- + struct name_record *n;
- + struct name_record *next;
-
- - p += 1;
- - while (numnames--)
- - {
- - char qname[17];
- - int type;
- - fstring flags="";
- - StrnCpy(qname,p,15);
- - type = CVAL(p,15);
- - p += 16;
- -
- - if (p[0] & 0x80) strcat(flags,"<GROUP> ");
- - if (p[0] & 0x60 == 0) strcat(flags,"B ");
- - if (p[0] & 0x60 == 1) strcat(flags,"P ");
- - if (p[0] & 0x60 == 2) strcat(flags,"M ");
- - if (p[0] & 0x60 == 3) strcat(flags,"_ ");
- - if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
- - if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
- - if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
- - if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
- + if (!lastrun) lastrun = t;
- + if (t < lastrun + 5*60) return;
-
- - if (master && type == 0x1d) {
- - StrnCpy(master,qname,15);
- - }
- -
- - DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags));
- - p+=2;
- + lastrun = t;
- +
- + for (n = namelist; n; n = next) {
- + if (n->death_time && n->death_time < t) {
- + DEBUG(3,("Removing dead name %s(%x)\n",
- + n->name.name,n->name.name_type));
- + next = n->next;
- + if (n->prev) n->prev->next = n->next;
- + if (n->next) n->next->prev = n->prev;
- + if (namelist == n) namelist = n->next;
- + free(n);
- + } else {
- + next = n->next;
- }
- - DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
- - IVAL(p,20),IVAL(p,24)));
- + }
- }
-
- -
- /****************************************************************************
- -show a nmb message
- +load a netbios hosts file
- ****************************************************************************/
- -static void show_nmb(char *inbuf)
- +static void load_hosts_file(char *fname)
- {
- - int i,l;
- - int name_trn_id = RSVAL(inbuf,0);
- - int opcode = (CVAL(inbuf,2) >> 3) & 0xF;
- - int nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
- - int rcode = CVAL(inbuf,3) & 0xF;
- - int qdcount = RSVAL(inbuf,4);
- - int ancount = RSVAL(inbuf,6);
- - int nscount = RSVAL(inbuf,8);
- - int arcount = RSVAL(inbuf,10);
- - char name[100];
- -
- - if (DEBUGLEVEL < 3) return;
- -
- - DEBUG(3,("\nPACKET INTERPRETATION\n"));
- -
- - if (opcode == 5 && ((nm_flags & ~1) == 0x10) && rcode == 0)
- - DEBUG(3,("NAME REGISTRATION REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- -
- - if (opcode == 5 && ((nm_flags & ~1) == 0x00) && rcode == 0)
- - DEBUG(3,("NAME OVERWRITE REQUEST AND DEMAND (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- -
- - if (opcode == 9 && ((nm_flags & ~1) == 0x00) && rcode == 0)
- - DEBUG(3,("NAME REFRESH REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- -
- - if (opcode == 8)
- - DEBUG(3,("NAME REFRESH (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- -
- - if (opcode == 5 && nm_flags == 0x58 && rcode == 0)
- - DEBUG(3,("POSITIVE NAME REGISTRATION RESPONSE\n"));
- -
- - if (opcode == 5 && nm_flags == 0x58 && rcode != 0 && rcode != 7)
- - DEBUG(3,("NEGATIVE NAME REGISTRATION RESPONSE\n"));
- -
- - if (opcode == 5 && nm_flags == 0x50 && rcode == 0)
- - DEBUG(3,("END-NODE CHALLENGE REGISTRATION RESPONSE\n"));
- -
- - if (opcode == 5 && nm_flags == 0x58 && rcode != 0 && rcode == 7)
- - DEBUG(3,("NAME CONFLICT DEMAND\n"));
- -
- - if (opcode == 6 && (nm_flags&~1) == 0x00 && rcode == 0)
- - DEBUG(3,("NAME RELEASE REQUEST & DEMAND (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- -
- - if (opcode == 6 && (nm_flags&~1) == 0x40 && rcode == 0)
- - DEBUG(3,("POSITIVE NAME RELEASE RESPONSE\n"));
- -
- - if (opcode == 6 && (nm_flags&~1) == 0x40 && rcode != 0)
- - DEBUG(3,("NEGATIVE NAME RELEASE RESPONSE\n"));
- -
- - if (opcode == 0 && (nm_flags&~1) == 0x10 && rcode == 0)
- - DEBUG(3,("NAME QUERY REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- -
- - if (opcode == 0 && (nm_flags&~0x28) == 0x50 && rcode == 0)
- - DEBUG(3,("POSITIVE NAME QUERY RESPONSE\n"));
- -
- - if (opcode == 0 && (nm_flags&~0x08) == 0x50 && rcode != 0)
- - DEBUG(3,("NEGATIVE NAME QUERY RESPONSE\n"));
- -
- - if (opcode == 0 && nm_flags == 0x10 && rcode == 0)
- - DEBUG(3,("REDIRECT NAME QUERY RESPONSE\n"));
- -
- - if (opcode == 7 && nm_flags == 0x80 && rcode == 0)
- - DEBUG(3,("WAIT FOR ACKNOWLEDGEMENT RESPONSE\n"));
- -
- - if (opcode == 0 && (nm_flags&~1) == 0x00 && rcode == 0)
- - DEBUG(3,("NODE STATUS REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- -
- - if (opcode == 0 && nm_flags == 0x40 && rcode == 0)
- - {
- - DEBUG(3,("NODE STATUS RESPONSE\n"));
- - interpret_node_status(inbuf,NULL);
- - }
- -
- -
- - DEBUG(3,("name_trn_id=0x%x\nopcode=0x%x\nnm_flags=0x%x\nrcode=0x%x\n",
- - name_trn_id,opcode,nm_flags,rcode));
- - DEBUG(3,("qdcount=%d\nancount=%d\nnscount=%d\narcount=%d\n",
- - qdcount,ancount,nscount,arcount));
- -
- - l = 12;
- - for (i=0;i<qdcount;i++)
- - {
- - int type,class;
- - DEBUG(3,("QUESTION %d\n",i));
- - name_extract(inbuf,l,name);
- - l += name_len(inbuf+l);
- - type = RSVAL(inbuf+l,0);
- - class = RSVAL(inbuf+l,2);
- - l += 4;
- - DEBUG(3,("\t%s\n\ttype=0x%x\n\tclass=0x%x\n",name,type,class));
- - }
- + FILE *f = fopen(fname,"r");
- + pstring line;
- + if (!f) {
- + DEBUG(2,("Can't open lmhosts file %s\n",fname));
- + return;
- + }
-
- - for (i=0;i<(ancount + nscount + arcount);i++)
- + while (!feof(f))
- {
- - int type,class,ttl,rdlength;
- - DEBUG(3,("RESOURCE %d\n",i));
- - name_extract(inbuf,l,name);
- - l += name_len(inbuf + l);
- - type = RSVAL(inbuf+l,0);
- - class = RSVAL(inbuf+l,2);
- - ttl = RIVAL(inbuf+l,4);
- - rdlength = RSVAL(inbuf+l,8);
- - l += 10 + rdlength;
- - DEBUG(3,("\t%s\n\ttype=0x%x\n\tclass=0x%x\n",name,type,class));
- - DEBUG(3,("\tttl=%d\n\trdlength=%d\n",ttl,rdlength));
- - }
- + if (!fgets_slash(line,sizeof(pstring),f)) continue;
- +
- + if (*line == '#') continue;
-
- - DEBUG(3,("\n"));
- -
- -}
- + {
- + BOOL group=False;
- + string ip="",name="",flags="",extra="";
- + char *ptr;
- + int count = 0;
- + struct in_addr ipaddr;
- + enum name_source source = LMHOSTS;
-
- + ptr = line;
-
- -/****************************************************************************
- -do a netbios name status to a host
- -****************************************************************************/
- -static BOOL name_status(char *name,int type,struct in_addr to_ip,char *master)
- -{
- - pstring inbuf,outbuf;
- - static uint16 name_trn_id = 0x4262;
- - char *p;
- - int retries = 2;
- - int retry_time = 5000;
- - struct timeval tval;
- + if (next_token(&ptr,ip,NULL)) ++count;
- + if (next_token(&ptr,name,NULL)) ++count;
- + if (next_token(&ptr,flags,NULL)) ++count;
- + if (next_token(&ptr,extra,NULL)) ++count;
-
- - bzero(inbuf,sizeof(inbuf));
- - bzero(outbuf,sizeof(outbuf));
- + if (count <= 0) continue;
-
- - name_trn_id += getpid() % 100;
- - name_trn_id = (name_trn_id % 10000);
- + if (count > 0 && count < 2)
- + {
- + DEBUG(0,("Ill formed hosts line [%s]\n",line));
- + continue;
- + }
-
- - RSSVAL(outbuf,0,name_trn_id);
- - CVAL(outbuf,2) = 0;
- - CVAL(outbuf,3) = 0x0;
- - RSSVAL(outbuf,4,1);
- - RSSVAL(outbuf,6,0);
- - RSSVAL(outbuf,8,0);
- - RSSVAL(outbuf,10,0);
- - p = outbuf+12;
- - name_mangle(name,p,type);
- - p += name_len(p);
- - RSSVAL(p,0,0x21);
- - RSSVAL(p,2,0x1);
- - p += 4;
- + if (strchr(flags,'G') || strchr(flags,'S'))
- + group = True;
-
- - show_nmb(outbuf);
- + if (strchr(flags,'M') && !group) {
- + source = SELF;
- + strcpy(myname,name);
- + }
-
- - GetTimeOfDay(&tval);
- + ipaddr = *interpret_addr2(ip);
-
- - if (!send_nmb(outbuf,nmb_len(outbuf), &to_ip, NMB_PORT))
- - return False;
- -
- - while (1)
- - {
- - struct timeval tval2;
- - GetTimeOfDay(&tval2);
- - if (TvalDiff(&tval,&tval2) > retry_time) {
- - if (!retries) break;
- - if (!send_nmb(outbuf,nmb_len(outbuf), &to_ip, NMB_PORT))
- - return False;
- - GetTimeOfDay(&tval);
- - retries--;
- - }
- -
- - if (receive_nmb(inbuf,90))
- - {
- - int rec_name_trn_id = RSVAL(inbuf,0);
- - int rcode = CVAL(inbuf,3) & 0xF;
- - int response = (CVAL(inbuf,2)>>7);
- - int qdcount = RSVAL(inbuf,4);
- - int ancount = RSVAL(inbuf,6);
- -
- - show_nmb(inbuf);
- -
- - /* is it a positive response to our request? */
- - if (response && (rec_name_trn_id == name_trn_id)) {
- - if (rcode==0 && ancount==1 && qdcount==0) {
- - interpret_node_status(inbuf, master);
- - return(True);
- - }
- - return(False);
- - }
- + if (group) {
- + add_domain_entry(name,ipaddr);
- + } else {
- + add_host_entry(name,0x20,True,0,source,ipaddr);
- }
- + }
- }
-
- - DEBUG(0,("No status response (this is not unusual)\n"));
- -
- - return(False);
- + fclose(f);
- }
-
- -/****************************************************************************
- -construct a host announcement unicast
- -****************************************************************************/
- -static BOOL send_udp_dgram(char *buf,int len,
- - char *srcname,char *dstname,
- - int src_type,int dest_type,
- - struct in_addr dest_ip)
- +/*******************************************************************
- + check if 2 IPs are on the same net
- + we will assume the local netmask, although this could be wrong XXXX
- + ******************************************************************/
- +static BOOL same_net(struct in_addr ip1,struct in_addr ip2)
- {
- - pstring outbuf;
- - char *p,*p2;
- - static int id=0;
- - char tmp[4];
- - struct sockaddr_in sock_out;
- -
- - bzero(outbuf,sizeof(outbuf));
- - RSSVAL(outbuf,0,0x1102); /* what is this? */
- - RSSVAL(outbuf,2,++id);
- - putip(outbuf+4,(void *)&myip);
- - RSSVAL(outbuf,8,DGRAM_PORT);
- - RSSVAL(outbuf,12,0);
- - p = outbuf + 14;
- - p += name_mangle(srcname,p,src_type);
- - p += name_mangle(dstname,p,dest_type);
- -
- - /* now setup the smb part */
- - p -= 4;
- - memcpy(tmp,p,4);
- - set_message(p,17,17 + len,True);
- - memcpy(p,tmp,4);
- -
- - CVAL(p,smb_com) = SMBtrans;
- - SSVAL(p,smb_vwv1,len);
- - SSVAL(p,smb_vwv11,len);
- - SSVAL(p,smb_vwv12,86);
- - SSVAL(p,smb_vwv13,3);
- - SSVAL(p,smb_vwv14,1);
- - SSVAL(p,smb_vwv15,1);
- - SSVAL(p,smb_vwv16,2);
- - p2 = smb_buf(p);
- - strcpy(p2,"\\MAILSLOT\\BROWSE");
- - p2 = skip_string(p2,1);
- -
- - memcpy(p2,buf,len);
- - p2 += len;
- -
- - len = PTR_DIFF(p2,outbuf);
- - RSSVAL(outbuf,10,len);
- -
- -
- - /* set the address and port */
- - bzero((char *)&sock_out,sizeof(sock_out));
- - putip((char *)&sock_out.sin_addr,(char *)&dest_ip);
- - sock_out.sin_port = htons(DGRAM_PORT);
- - sock_out.sin_family = AF_INET;
- -
- - /* log the packet */
- - log_out(outbuf,len);
- -
- - /* send it */
- - if (sendto(ClientDGRAM,outbuf,len,0,
- - (struct sockaddr *)&sock_out,sizeof(sock_out)) < 0) {
- - DEBUG(3,("Sendto failed errno=%d (%s)\n",errno,strerror(errno)));
- - return(False);
- - }
- + unsigned int net1,net2,nmask;
-
- - return(True);
- + putip((char *)&nmask,(char *)&Netmask);
- + putip((char *)&net1,(char *)&ip1);
- + putip((char *)&net2,(char *)&ip2);
- +
- + return((net1 & nmask) == (net2 & nmask));
- }
-
- +
- /****************************************************************************
- -construct a host announcement unicast
- -****************************************************************************/
- -static void announce_host(int i,char *my_name,char *Comment)
- + construct a host announcement unicast
- + **************************************************************************/
- +static void announce_host(struct domain_record *d,char *my_name,char *Comment)
- {
- - static int announce_interval = 1;
- - char *group = names[i].name;
- - struct in_addr dest_ip = names[i].ip;
- + time_t t = time(NULL);
- pstring outbuf;
- char *p;
-
- - names[i].count++;
- -
- - if ((names[i].count % announce_interval) != 0) return;
- + /* announce every minute at first then progress to every 15 mins */
- + if (d->lastannounce_time &&
- + (t - d->lastannounce_time) < d->announce_interval)
- + return;
-
- - if (announce_interval < 2) announce_interval++;
- + if (d->announce_interval < 15*60) d->announce_interval += 60;
- + d->lastannounce_time = t;
-
- - DEBUG(2,("Sending host announcement to %s for group %s\n",
- - inet_ntoa(dest_ip),group));
- + DEBUG(2,("Sending host announcement to %s for workgroup %s\n",
- + inet_ntoa(d->bcast_ip),d->name));
-
- if (!*Comment) Comment = "NoComment";
- if (!*my_name) my_name = "NoName";
- - if (!*group) group = "NoGroup";
-
- - if (strlen(Comment) > 47) Comment[47] = 0;
- + if (strlen(Comment) > 43) Comment[43] = 0;
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
- CVAL(p,0) = 1; /* host announce */
- SSVAL(p,1,0x6006); /* update count?? */
- CVAL(p,3) = 0xEA; /* res1 */
- - SSVAL(p,4,announce_interval);
- + SSVAL(p,4,d->announce_interval);
- p += 6;
- StrnCpy(p,my_name,16);
- strupper(p);
- @@ -837,361 +443,141 @@
- strcpy(p,Comment);
- p += strlen(p)+1;
-
- - send_udp_dgram(outbuf,PTR_DIFF(p,outbuf),my_name,group,0,0x1d,dest_ip);
- -}
- -
- -
- -
- -/****************************************************************************
- -send a name registration packet
- -****************************************************************************/
- -static void send_registration(char *name,int name_type,struct in_addr dest_ip,struct in_addr ip,BOOL refresh,int ttl)
- -{
- - char *p;
- - static int t = 0x176;
- - pstring outbuf;
- - bzero(outbuf,sizeof(outbuf));
- - /* send a registration request */
- - RSSVAL(outbuf,0,t++);
- - if (refresh)
- - CVAL(outbuf,2) = (0<<7) | (9<<3) | 0;
- - else
- - CVAL(outbuf,2) = (0<<7) | (5<<3) | 1;
- -
- - CVAL(outbuf,3) = (1<<4);
- - RSSVAL(outbuf,4,1);
- - RSSVAL(outbuf,6,0);
- - RSSVAL(outbuf,8,0);
- - RSSVAL(outbuf,10,1);
- - p = outbuf+12;
- - name_mangle(name,p,name_type);
- - p += name_len(p);
- - RSSVAL(p,0,0x20);
- - RSSVAL(p,2,0x1);
- - p += 4;
- - RSSVAL(p,0,12);
- - CVAL(p,0) = CVAL(p,0) | 0xC0;
- - p += 2;
- - RSSVAL(p,0,0x20);
- - RSSVAL(p,2,0x1);
- - p += 4;
- - RSIVAL(p,0,ttl);
- -
- - RSSVAL(p,4,6);
- - RSSVAL(p,6,0);
- - p += 8;
- - putip(p,&ip);
- - p += 4;
- -
- - DEBUG(2,("Sending a name registration request\n"));
- - if (DEBUGLEVEL > 2)
- - show_nmb(outbuf);
- -
- - send_nmb(outbuf,PTR_DIFF(p,outbuf),&dest_ip,NMB_PORT);
- -}
- -
- -/*******************************************************************
- -find a master browser
- -********************************************************************/
- -BOOL find_master(char *name1,struct in_addr ip,struct in_addr *ipout)
- -{
- - int type = 0x1d;
- - fstring name;
- - BOOL ret;
- - strcpy(name,name1);
- - if (strequal(name,"*")) {
- - strcpy(name,"\001\002__MSBROWSE__\002");
- - type = 1;
- - }
- - ret = name_query(name,type,True,False,ip,ipout);
- - if (!ret) return(False);
- - if (type != 1) return(True);
- -
- - name_status(name,type,*ipout,name1);
- - return(name1[0] != '*');
- + send_udp_dgram(ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
- + my_name,d->name,0,0x1d,d->bcast_ip,myip);
- }
-
- -/****************************************************************************
- -process a workgroup announce frame
- -****************************************************************************/
- -static void process_workgroup_announce(char *group,struct in_addr ip)
- -{
- - int i;
- - for (i=0;i<num_names;i++)
- - if (names[i].valid) {
- - if (names[i].name[0] == '*') {
- - StrnCpy(names[i].name,group,15);
- - names[i].master_ip = ip;
- - names[i].found_master = True;
- - names[i].count=0;
- - announce_host(i,myname,comment);
- - return;
- - }
- - if (names[i].isgroup && name_equal(names[i].name,group,0,0)) {
- - int j;
- - for (j=i;j<num_names;j++)
- - if (names[j].valid && names[j].isgroup && names[i].found_master &&
- - name_equal(names[i].name,group,0,0)) return;
- - names[i].master_ip = ip;
- - names[i].found_master = True;
- - names[i].count=0;
- - announce_host(i,myname,comment);
- - return;
- - }
- - }
- -}
- -
-
- /****************************************************************************
- process a browse frame
- ****************************************************************************/
- -static void process_browse_packet(char *buf,int len)
- +static void process_browse_packet(struct packet_struct *p,char *buf,int len)
- {
- - char *p;
- + /* don't actually do anything with these at the moment */
- +#if 0
- int command = CVAL(buf,0);
- switch (command) {
- - case 0xc: /* workgroup announcement */
- + case 0xc: /* domain announcement */
- {
- fstring group;
- - p = buf + 6;
- - StrnCpy(group,p,15);
- + StrnCpy(group,buf+6,15);
- DEBUG(2,("Got workgroup announce for %s (%s)\n",
- group,inet_ntoa(lastip)));
- - process_workgroup_announce(group,lastip);
- + process_workgroup_announce(p,group);
- break;
- }
- }
- -
- +#endif
- }
-
- +
- /****************************************************************************
- process udp 138 datagrams
- ****************************************************************************/
- -static void process_dgram(void)
- +static void process_dgram(struct packet_struct *p)
- {
- - pstring inbuf;
- + char *buf;
- int len;
- - while (read_max_udp(ClientDGRAM,inbuf,sizeof(inbuf),1) > 4) {
- - char *p = inbuf;
- - len = RSVAL(inbuf,10);
- - p += 14;
- - p += name_len(p);
- - p += name_len(p);
- - p -= 4;
- - if (CVAL(p,smb_com) != SMBtrans) continue;
- - if (!strequal(smb_buf(p),"\\MAILSLOT\\BROWSE")) continue;
- - len = SVAL(p,smb_vwv11);
- - p = smb_base(p) + SVAL(p,smb_vwv12);
- - if (len <= 0) continue;
- - process_browse_packet(p,len);
- + struct dgram_packet *dgram = &p->packet.dgram;
- +
- + if (dgram->header.msg_type != 0x10 &&
- + dgram->header.msg_type != 0x11 &&
- + dgram->header.msg_type != 0x12) {
- + /* don't process error packets etc yet */
- + return;
- }
- -}
-
- -/****************************************************************************
- -a hook for registration of my own names
- -****************************************************************************/
- -static void do_registration_hook(void)
- -{
- - static int count = 0;
- - static time_t last_t=0;
- - time_t t = time(NULL);
- -
- - if (last_t && (t-last_t)<REGISTRATION_INTERVAL) return;
- - last_t = t;
- -
- - send_registration(myname,0x20,bcast_ip,myip,count>0,300000);
- - count++;
- + buf = &dgram->data[0];
- + buf -= 4; /* XXXX for the pseudo tcp length -
- + someday I need to get rid of this */
- +
- + if (CVAL(buf,smb_com) != SMBtrans) return;
- + if (!strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE")) return;
- + len = SVAL(buf,smb_vwv11);
- + buf = smb_base(buf) + SVAL(buf,smb_vwv12);
- + if (len <= 0) return;
- + process_browse_packet(p,buf,len);
- }
-
- -/****************************************************************************
- -a hook for browsing handling - called every BROWSE_INTERVAL secs
- -****************************************************************************/
- -static void do_browse_hook(void)
- +/*******************************************************************
- + find a workgroup using the specified broadcast
- + ******************************************************************/
- +static BOOL find_workgroup(char *name,struct in_addr ip)
- {
- - static BOOL first = True;
- - int i;
- - static time_t last_t=0;
- - time_t t = time(NULL);
- -
- - if (last_t && (t-last_t)<browse_interval) return;
- - last_t = t;
- -
- - for (i=0;i<num_names;i++)
- - {
- - BOOL old_found_master = names[i].found_master;
- + fstring name1;
- + BOOL ret;
- + struct in_addr ipout;
-
- - if (!NAMEVALID(i) || !ISGROUP(i)) continue;
- + strcpy(name1,"\001\002__MSBROWSE__\002");
-
- - if (names[i].found_master) {
- - struct in_addr ip2;
- - announce_host(i,myname,comment);
- -
- - if (!name_query(names[i].name,0x1d,True,False,
- - names[i].master_ip,
- - &ip2)) {
- - DEBUG(2,("%s Master browser at %s failed to respond\n",
- - timestring(),
- - inet_ntoa(names[i].master_ip)));
- - names[i].found_master = False;
- - } else {
- - names[i].master_ip = ip2;
- - }
- - }
- + ret = name_query(ClientNMB,name1,0x1,True,False,ip,&ipout,queue_packet);
- + if (!ret) return(False);
-
- - if (!names[i].found_master) {
- - struct in_addr ip2;
- - names[i].found_master = find_master(names[i].name,names[i].ip,&ip2);
- -
- - if (names[i].found_master) {
- - names[i].master_ip = ip2;
- - DEBUG(1,("%s New master browser for %s at %s\n",
- - timestring(),
- - names[i].name,inet_ntoa(names[i].master_ip)));
- - names[i].count = 0;
- - announce_host(i,myname,comment);
- - }
- - }
- + name_status(ClientNMB,name1,0x1,False,ipout,name,queue_packet);
-
- - if (!names[i].found_master) {
- - int level = (old_found_master||first)?1:2;
- - DEBUG(level,("%s Failed to find a master browser for %s using %s\n",
- - timestring(),
- - names[i].name,inet_ntoa(names[i].ip)));
- - }
- - }
- - first = False;
- + if (name[0] != '*') {
- + DEBUG(2,("Found workgroup %s on broadcast %s\n",name,inet_ntoa(ip)));
- + } else {
- + DEBUG(3,("Failed to find workgroup %s on broadcast %s\n",name,inet_ntoa(ip)));
- + }
- + return(name[0] != '*');
- }
-
-
- /****************************************************************************
- - do a netbios name query to find someones IP
- - ****************************************************************************/
- -static BOOL name_query(char *name,int name_type, BOOL bcast,BOOL recurse,
- - struct in_addr to_ip, struct in_addr *ip)
- + a hook for browsing handling - called every minute
- + **************************************************************************/
- +static void do_browse_hook(void)
- {
- - BOOL found=False;
- - static uint16 name_trn_id = 0;
- - int retries = 3;
- - int retry_time = bcast?250:5000;
- - struct timeval tval;
- - struct packet_struct p;
- - struct packet_struct *p2;
- - struct nmb_packet *nmb = &p.packet.nmb;
- -
- - bzero((char *)&p,sizeof(p));
- -
- - if (!name_trn_id) name_trn_id = (time(NULL)%0x7FFF) + (getpid()%100);
- - name_trn_id = (name_trn_id+1) % 0x7FFF;
- -
- - nmb->header.name_trn_id = name_trn_id;
- - nmb->header.opcode = 0;
- - nmb->header.response = False;
- - nmb->header.nm_flags.bcast = bcast;
- - nmb->header.nm_flags.recursion_available = CanRecurse;
- - nmb->header.nm_flags.recursion_desired = recurse;
- - nmb->header.nm_flags.trunc = False;
- - nmb->header.nm_flags.authoritative = False;
- - nmb->header.rcode = 0;
- - nmb->header.qdcount = 1;
- - nmb->header.ancount = 0;
- - nmb->header.nscount = 0;
- - nmb->header.arcount = 0;
- -
- - strcpy(nmb->question.question_name.name,name);
- - strupper(nmb->question.question_name.name);
- - nmb->question.question_name.name_type = name_type;
- - strcpy(nmb->question.question_name.scope,scope);
- -
- - nmb->question.question_type = 0x20;
- - nmb->question.question_class = 0x1;
- -
- - p.ip = to_ip;
- - p.port = NMB_PORT;
- - p.fd = ClientNMB;
- - p.timestamp = time(NULL);
- - p.packet_type = NMB_PACKET;
- -
- - GetTimeOfDay(&tval);
- -
- - if (!send_packet(&p))
- - return(False);
- -
- - retries--;
- -
- - while (1)
- - {
- - struct timeval tval2;
- - GetTimeOfDay(&tval2);
- - if (TvalDiff(&tval,&tval2) > retry_time) {
- - if (!retries) break;
- - if (!found && !send_packet(&p))
- - return False;
- - GetTimeOfDay(&tval);
- - retries--;
- - }
- + struct domain_record *d;
-
- - if ((p2=receive_packet(ClientNMB,NMB_PACKET,90)))
- - {
- - struct nmb_packet *nmb2 = &p2->packet.nmb;
- - if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
- - !nmb2->header.response) {
- - /* its not for us - deal with it later */
- - queue_packet(p2);
- - continue;
- - }
- -
- - if (nmb2->header.opcode != 0 ||
- - nmb2->header.nm_flags.bcast ||
- - nmb2->header.rcode ||
- - !nmb2->header.ancount) {
- - /* XXXX what do we do with this? could be a redirect, but
- - we'll discard it for the moment */
- - free_packet(p2);
- - continue;
- - }
- + for (d = domainlist; d; d = d->next) {
- + /* if the ip address is 0 then set to the broadcast */
- + if (zero_ip(d->bcast_ip)) d->bcast_ip = bcast_ip;
-
- - putip((char *)ip,&nmb2->answers->rdata[2]);
- - DEBUG(2,("Got a positive name query response from %s",
- - inet_ntoa(p2->ip)));
- - DEBUG(2,(" (%s)\n",inet_ntoa(*ip)));
- - found=True; retries=0;
- - }
- + /* if the workgroup is '*' then find a workgroup to be part of */
- + if (d->name[0] == '*') {
- + if (!find_workgroup(d->name,d->bcast_ip)) continue;
- + add_host_entry(d->name,0x1e,False,0,SELF,*interpret_addr2("255.255.255.255"));
- }
-
- - return(found);
- + announce_host(d,myname,comment);
- + }
- }
-
-
- +
- /****************************************************************************
- reply to a name release
- ****************************************************************************/
- static void reply_name_release(struct packet_struct *p)
- {
- struct nmb_packet *nmb = &p->packet.nmb;
- - char *qname = nmb->question.question_name.name;
- - BOOL wildcard = (qname[0] == '*');
- - int name_type = nmb->question.question_name.name_type;
- - int nb_flags = nmb->additional->rdata[0];
- struct packet_struct p2;
- struct nmb_packet *nmb2;
- struct res_rec answer_rec;
- struct in_addr ip;
- - BOOL release_ok=False;
- - int reason=5;
- - int n;
- -
- - if (wildcard) return;
- + int rcode=0;
- + int nb_flags = nmb->additional->rdata[0];
-
- putip((char *)&ip,&nmb->additional->rdata[2]);
-
- - n = find_name(qname,name_type,True);
- - if (n>=0 && names[n].source == REGISTER &&
- - !memcmp((char *)&ip,(char *)&names[n].ip,sizeof(ip))) {
- - release_ok = True;
- - names[n].valid = False;
- + {
- + struct name_record *n = find_name(&nmb->question.question_name);
- + if (n && n->unique && n->source == REGISTER &&
- + ip_equal(ip,n->ip)) {
- + remove_name(n); n = NULL;
- + }
- +
- + /* XXXX under what conditions should we reject the removal?? */
- }
-
- - /* Send a POSITIVE NAME RELEASE RESPONSE */
- + DEBUG(3,("Name release on name %s(%x) rcode=%d\n",
- + nmb->question.question_name.name,
- + nmb->question.question_name.name_type,rcode));
- +
- +
- + /* Send a NAME RELEASE RESPONSE */
- p2 = *p;
- nmb2 = &p2.packet.nmb;
-
- @@ -1204,7 +590,7 @@
- nmb2->header.ancount = 1;
- nmb2->header.nscount = 0;
- nmb2->header.arcount = 0;
- - nmb2->header.rcode = release_ok?0:reason;
- + nmb2->header.rcode = rcode;
-
- nmb2->answers = &answer_rec;
- bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
- @@ -1231,50 +617,59 @@
- char *qname = nmb->question.question_name.name;
- BOOL wildcard = (qname[0] == '*');
- BOOL bcast = nmb->header.nm_flags.bcast;
- - int name_type = nmb->question.question_name.name_type;
- int ttl = nmb->additional->ttl;
- + int name_type = nmb->question.question_name.name_type;
- int nb_flags = nmb->additional->rdata[0];
- struct packet_struct p2;
- struct nmb_packet *nmb2;
- struct res_rec answer_rec;
- struct in_addr ip;
- + BOOL group = (nb_flags&0x80)?True:False;
- + int rcode = 0;
-
- if (wildcard) return;
-
- putip((char *)&ip,&nmb->additional->rdata[2]);
-
- - if ((nb_flags&0x80) == 0 && (name_type != 0x1d)) {
- - int n = find_name(qname,name_type,True);
- - if (ttl==0) ttl = NMBD_MAX_TTL;
- - ttl = MIN(ttl,NMBD_MAX_TTL);
- + if (group) {
- + /* apparently we should return 255.255.255.255 for group queries (email from MS) */
- + ip = *interpret_addr2("255.255.255.255");
- + }
-
- - if (n>=0 && names[n].source != REGISTER && names[n].source != DNS)
- - return;
- + {
- + struct name_record *n = find_name(&nmb->question.question_name);
-
- - if (n<0)
- - n = add_name();
- - if (n<0) return;
- -
- - bzero(&names[n],sizeof(names[n]));
- -
- - StrnCpy(names[n].name,qname,15);
- - names[n].type = name_type;
- - names[n].unicast = !dns_serve || is_mynet(ip);
- - names[n].ip = ip;
- - names[n].valid = True;
- - names[n].ttl = ttl;
- - names[n].source = REGISTER;
- - names[n].start_time = p->timestamp;
- + if (n) {
- + if (!group && !ip_equal(ip,n->ip)) {
- + /* check if the previous owner still wants it,
- + if so reject the registration, otherwise change the owner
- + and refresh */
- + /* XXXXXX not done yet */
- + rcode = 5;
- + } else {
- + /* refresh the name */
- + n->death_time = ttl?p->timestamp + ttl:0;
- + }
- + } else {
- + /* add the name to our database */
- + n = add_host_entry(qname,name_type,!group,ttl,REGISTER,ip);
- + }
- }
-
- if (bcast) return;
-
- - /* Send a POSITIVE NAME REGISTRATION RESPONSE */
- + DEBUG(3,("Name registration for name %s(%x) at %s rcode=%d\n",
- + nmb->question.question_name.name,
- + nmb->question.question_name.name_type,
- + inet_ntoa(ip),rcode));
- +
- + /* Send a NAME REGISTRATION RESPONSE */
- /* a lot of fields get copied from the query. This gives us the IP
- and port the reply will be sent to etc */
- p2 = *p;
- nmb2 = &p2.packet.nmb;
-
- + nmb2->header.opcode = 5;
- nmb2->header.response = True;
- nmb2->header.nm_flags.bcast = False;
- nmb2->header.nm_flags.recursion_available = CanRecurse;
- @@ -1284,6 +679,7 @@
- nmb2->header.ancount = 1;
- nmb2->header.nscount = 0;
- nmb2->header.arcount = 0;
- + nmb2->header.rcode = rcode;
-
- nmb2->answers = &answer_rec;
- bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
- @@ -1292,10 +688,6 @@
- nmb2->answers->rr_type = nmb->question.question_type;
- nmb2->answers->rr_class = nmb->question.question_class;
-
- - /* we want them to refresh in case we die */
- - if (!ttl) ttl = 15*60;
- - ttl = MIN(ttl,15*60);
- -
- nmb2->answers->ttl = ttl;
- nmb2->answers->rdlength = 6;
- nmb2->answers->rdata[0] = nb_flags;
- @@ -1313,22 +705,23 @@
- struct nmb_packet *nmb = &p->packet.nmb;
- char *qname = nmb->question.question_name.name;
- BOOL wildcard = (qname[0] == '*');
- - int name_type = nmb->question.question_name.name_type;
- struct packet_struct p2;
- struct nmb_packet *nmb2;
- struct res_rec answer_rec;
- char *buf;
- - int count,i;
- + int count;
- + int rcode = 0;
- + struct name_record *n = find_name(&nmb->question.question_name);
-
- - if (!wildcard) {
- - i = find_name(qname,name_type,False);
- + if (!wildcard && (!n || n->source != SELF))
- + return;
-
- - if (i < 0)
- - return;
- - if (names[i].source != SELF && names[i].source != LMHOSTS)
- - return;
- - }
-
- + DEBUG(3,("Name status for name %s(%x) rcode=%d\n",
- + nmb->question.question_name.name,
- + nmb->question.question_name.name_type,
- + rcode));
- +
- /* Send a POSITIVE NAME STATUS RESPONSE */
- /* a lot of fields get copied from the query. This gives us the IP
- and port the reply will be sent to etc */
- @@ -1345,6 +738,7 @@
- nmb2->header.ancount = 1;
- nmb2->header.nscount = 0;
- nmb2->header.arcount = 0;
- + nmb2->header.rcode = rcode;
-
- nmb2->answers = &answer_rec;
- bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
- @@ -1355,8 +749,8 @@
- nmb2->answers->rr_class = nmb->question.question_class;
- nmb2->answers->ttl = 0; /* XXX what ttl to answer with? */
-
- - for (count=0,i=0;i<num_names;i++)
- - if (names[i].valid) count++;
- + for (count=0, n = namelist ; n; n = n->next) count++;
- +
- count = MIN(count,400/18); /* XXXX hack, we should calculate exactly
- how many will fit */
-
- @@ -1365,20 +759,19 @@
- SCVAL(buf,0,count);
- buf += 1;
-
- - for (i=0;i<num_names && count>0;i++)
- - if (names[i].valid)
- - {
- - bzero(buf,18);
- - strcpy(buf,names[i].name);
- - strupper(buf);
- - buf[15] = names[i].type;
- - buf += 16;
- - buf[0] = 0x4; /* active */
- - if (strequal(names[i].name,myname)) buf[0] |= 0x2; /* permanent */
- - if (ISGROUP(i)) buf[0] |= 0x80; /* group */
- - buf += 2;
- - count--;
- - }
- + for (n = namelist ; n; n = n->next)
- + {
- + bzero(buf,18);
- + strcpy(buf,n->name.name);
- + strupper(buf);
- + buf[15] = n->name.name_type;
- + buf += 16;
- + buf[0] = 0x4; /* active */
- + if (strequal(n->name.name,myname)) buf[0] |= 0x2; /* permanent */
- + if (!n->unique) buf[0] |= 0x80; /* group */
- + buf += 2;
- + count--;
- + }
-
- /* we should fill in more fields of the statistics structure */
- bzero(buf,46);
- @@ -1412,61 +805,69 @@
- struct packet_struct p2;
- struct nmb_packet *nmb2;
- struct res_rec answer_rec;
- + int ttl=0;
- + int rcode=0;
- + BOOL unique = True;
- +
- + if (wildcard)
- + retip = myip;
-
- if (!wildcard) {
- - int i = find_name(qname,name_type,False);
- + struct name_record *n = find_name(&nmb->question.question_name);
-
- - if (i < 0)
- - i = find_name(qname,name_type,True);
- -
- - if (i >= 0)
- - {
- - if (bcast && (names[i].unicast || names[i].source == REGISTER))
- - return;
- -
- - if (ISGROUP(i))
- - return;
- + if (!n) {
- + struct in_addr ip;
- + unsigned long a;
- +
- + /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
- + if (name_type != 0x20 && name_type != 0) return;
-
- - retip = names[i].ip;
- + /* look it up with DNS */
- + a = interpret_addr(qname);
- +
- + if (!a) {
- + /* no luck with DNS. We could possibly recurse here XXXX */
- + return;
- }
- - else
- - {
- - if ((name_type!=0 && name_type!=0x3 && name_type!=0x20) ||
- - (bcast && !dns_serve)) {
- - return;
- - } else {
- - unsigned long a;
-
- - a = interpret_addr(qname);
- - if (!a) return;
- + /* add it to our cache of names. give it 2 hours in the cache */
- + putip((char *)&ip,(char *)&a);
- + n = add_host_entry(qname,name_type,True,2*60*60,DNS,ip);
-
- - /* here is where we might recurse */
- - putip((char *)&retip,(char *)&a);
- -
- - if (bcast && is_mynet(retip))
- - return;
- + /* failed to add it? yikes! */
- + if (!n) return;
- + }
-
- - i = find_name(qname,name_type,True);
- - if (i < 0) {
- - if ((i=add_name())>=0) {
- - StrnCpy(names[i].name,qname,15);
- - names[i].type = name_type;
- - names[i].unicast = is_mynet(retip);
- - names[i].ip = retip;
- - names[i].valid = True;
- - names[i].ttl = 120; /* give it two minutes */
- - names[i].start_time = p->timestamp;
- - names[i].source = DNS;
- - }
- - }
- - }
- - DEBUG(2,(" sending positive reply (%s)\n",inet_ntoa(retip)));
- - }
- - } else {
- - retip = myip;
- - }
- + /* don't respond to bcast queries for group names */
- + if (bcast && !n->unique) return;
- +
- + /* don't respond to bcast queries for addresses on the same net as the machine
- + doing the querying unless its our IP (or something from LMHOSTS) */
- + if (bcast &&
- + n->source != SELF && n->source != LMHOSTS &&
- + same_net(n->ip,p->ip)) return;
- +
- + /* is our entry already dead? */
- + if (n->death_time) {
- + if (n->death_time < p->timestamp) return;
- + ttl = n->death_time - p->timestamp;
- + }
- +
- + retip = n->ip;
- + unique = n->unique;
- + }
- +
- + /* if the IP is 0 then substitute my IP - we should see which one is on the
- + right interface for the caller to do this right */
- + if (zero_ip(retip)) retip = myip;
-
-
- + DEBUG(3,("Name query for name %s(%x) at %s rcode=%d\n",
- + nmb->question.question_name.name,
- + nmb->question.question_name.name_type,
- + inet_ntoa(retip),rcode));
- +
- +
- /* a lot of fields get copied from the query. This gives us the IP
- and port the reply will be sent to etc */
- p2 = *p;
- @@ -1482,6 +883,7 @@
- nmb2->header.ancount = 1;
- nmb2->header.nscount = 0;
- nmb2->header.arcount = 0;
- + nmb2->header.rcode = rcode;
-
- nmb2->answers = &answer_rec;
- bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
- @@ -1489,9 +891,9 @@
- nmb2->answers->rr_name = nmb->question.question_name;
- nmb2->answers->rr_type = nmb->question.question_type;
- nmb2->answers->rr_class = nmb->question.question_class;
- - nmb2->answers->ttl = 0; /* XXX what ttl to answer with? */
- + nmb2->answers->ttl = ttl; /* XXX what ttl to answer with? */
- nmb2->answers->rdlength = 6;
- - nmb2->answers->rdata[0] = 0; /* XXXX nbflags - what should this be? */
- + nmb2->answers->rdata[0] = unique?0:0x80;
- nmb2->answers->rdata[1] = 0;
- putip(&nmb2->answers->rdata[2],(char *)&retip);
-
- @@ -1598,7 +1000,7 @@
- break;
-
- case DGRAM_PACKET:
- - /* process_dgram(p); */
- + process_dgram(p);
- break;
- }
-
- @@ -1614,15 +1016,13 @@
- ***************************************************************************/
- void process(void)
- {
- +
- while (True)
- {
- fd_set fds;
- int selrtn;
- struct timeval timeout;
-
- - do_registration_hook();
- - do_browse_hook();
- -
- FD_ZERO(&fds);
- FD_SET(ClientNMB,&fds);
- FD_SET(ClientDGRAM,&fds);
- @@ -1642,6 +1042,10 @@
- }
-
- run_packet_queue();
- +
- + do_browse_hook();
- +
- + housekeeping();
- }
- }
-
- @@ -1661,7 +1065,7 @@
- }
-
- if (isdaemon)
- - ClientNMB = open_socket_in(SOCK_DGRAM, port,*lookup?3:0);
- + ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
- else
- ClientNMB = 0;
-
- @@ -1723,10 +1127,6 @@
- if (p) *p = 0;
- }
-
- - add_host_name(myname,0x20,&myip);
- - add_host_name(myname,0x0,&myip);
- - add_host_name(myname,0x3,&myip);
- -
- return True;
- }
-
- @@ -1740,21 +1140,14 @@
- printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
- printf("Version %s\n",VERSION);
- printf("\t-D become a daemon\n");
- - printf("\t-P passive only. don't respond\n");
- - printf("\t-R only reply to queries, don't actively send claims\n");
- printf("\t-p port listen on the specified port\n");
- printf("\t-d debuglevel set the debuglevel\n");
- printf("\t-l log basename. Basename for log/debug files\n");
- printf("\t-n netbiosname. the netbios name to advertise for this host\n");
- printf("\t-B broadcast address the address to use for broadcasts\n");
- printf("\t-N netmask the netmask to use for subnet determination\n");
- - printf("\t-L name lookup this netbios name then exit\n");
- - printf("\t-S serve queries via DNS if not on the same subnet\n");
- printf("\t-H hosts file load a netbios hosts file\n");
- printf("\t-G group name add a group name to be part of\n");
- - printf("\t-b toggles browsing support (defaults to on)\n");
- - printf("\t-M group name searches for a master browser for the given group\n");
- - printf("\t-T interval sets the browse announcement interval in seconds\n");
- printf("\t-C comment sets the machine comment that appears in browse lists\n");
- printf("\n");
- }
- @@ -1762,16 +1155,15 @@
-
- /****************************************************************************
- main program
- -****************************************************************************/
- + **************************************************************************/
- int main(int argc,char *argv[])
- {
- int port = NMB_PORT;
- int opt;
- - unsigned int lookup_type = 0;
- extern FILE *dbf;
- extern char *optarg;
-
- - *lookup = *host_file = 0;
- + *host_file = 0;
-
- TimeInit();
-
- @@ -1794,14 +1186,12 @@
-
- signal(SIGHUP,SIGNAL_CAST sig_hup);
-
- + bcast_ip = *interpret_addr2("0.0.0.0");
- + myip = *interpret_addr2("0.0.0.0");
-
- - while ((opt = getopt (argc, argv, "T:O:M:I:C:bAL:i:B:N:Rn:l:d:Dp:hPSH:G:")) != EOF)
- + while ((opt = getopt (argc, argv, "T:O:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
- switch (opt)
- {
- - case 'T':
- - browse_interval = atoi(optarg);
- - browse_interval = MAX(browse_interval,10);
- - break;
- case 'O':
- strcpy(user_socket_options,optarg);
- break;
- @@ -1809,47 +1199,26 @@
- strcpy(comment,optarg);
- break;
- case 'G':
- - add_group_name(optarg);
- + add_domain_entry(optarg,bcast_ip);
- break;
- - case 'A':
- - dns_serve = True;
- - break;
- case 'H':
- strcpy(host_file,optarg);
- break;
- case 'I':
- - {
- - unsigned long a = interpret_addr(optarg);
- - putip((char *)&myip,(char *)&a);
- - got_myip = True;
- - }
- + myip = *interpret_addr2(optarg);
- + got_myip = True;
- break;
- case 'B':
- - {
- - unsigned long a = interpret_addr(optarg);
- - putip((char *)&bcast_ip,(char *)&a);
- - got_bcast = True;
- - }
- + bcast_ip = *interpret_addr2(optarg);
- + got_bcast = True;
- break;
- case 'N':
- - {
- - unsigned long a = interpret_addr(optarg);
- - putip((char *)&Netmask,(char *)&a);
- - got_nmask = True;
- - }
- + Netmask = *interpret_addr2(optarg);
- + got_nmask = True;
- break;
- case 'n':
- strcpy(myname,optarg);
- break;
- - case 'P':
- - {
- - extern BOOL passive;
- - passive = True;
- - }
- - break;
- - case 'S':
- - dns_serve = !dns_serve;
- - break;
- case 'l':
- sprintf(debugf,"%s.nmb",optarg);
- break;
- @@ -1857,18 +1226,6 @@
- strcpy(scope,optarg);
- strupper(scope);
- break;
- - case 'L':
- - strcpy(lookup,optarg);
- - break;
- - case 'M':
- - if (*optarg == '-') {
- - strcpy(lookup,"\01\02__MSBROWSE__\02");
- - lookup_type = 1;
- - } else {
- - strcpy(lookup,optarg);
- - lookup_type = 0x1d;
- - }
- - break;
- case 'D':
- is_daemon = True;
- break;
- @@ -1888,9 +1245,6 @@
- }
-
-
- - if (*lookup)
- - DEBUGLEVEL++;
- -
- if (DEBUGLEVEL > 10)
- {
- extern FILE *login,*logout;
- @@ -1901,13 +1255,6 @@
- logout = fopen(fname,"w");
- }
-
- - if (*lookup)
- - {
- - if (dbf)
- - fclose(dbf);
- - dbf = stdout;
- - }
- -
- DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
- DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
-
- @@ -1919,34 +1266,12 @@
-
- init_structs();
-
- - if (*lookup) {
- - BOOL bcast = True;
- - int retries = 2;
- - char *p = strchr(lookup,'#');
- - struct in_addr ip;
- - if (p) {
- - *p = 0;
- - sscanf(p+1,"%x",&lookup_type);
- - bcast = False;
- - retries = 1;
- - }
- - if (!open_sockets(True,port)) return(1);
- - while (retries--)
- - if (name_query(lookup,lookup_type,bcast,True,bcast_ip,&ip)) {
- - printf("%s %s\n",inet_ntoa(ip),lookup);
- - name_status(lookup,lookup_type,ip,NULL);
- - return(0);
- - }
- - printf("couldn't find name %s\n",lookup);
- - return(0);
- - }
- -
- if (!*comment)
- strcpy(comment,"Samba %v");
- string_sub(comment,"%v",VERSION);
- string_sub(comment,"%h",myhostname);
-
- - check_names();
- + add_my_names();
-
- DEBUG(3,("Checked names\n"));
-
- diff -u -r --new-file last-version/source/nmblib.c samba-1.9.14p4/source/nmblib.c
- --- last-version/source/nmblib.c Tue Nov 7 22:25:10 1995
- +++ samba-1.9.14p4/source/nmblib.c Fri Nov 10 20:54:24 1995
- @@ -27,6 +27,9 @@
-
- int num_good_sends=0;
- int num_good_receives=0;
- +static uint16 name_trn_id = 0;
- +BOOL CanRecurse = True;
- +extern pstring scope;
-
- /*******************************************************************
- handle "compressed" name pointers
- @@ -116,11 +119,15 @@
- /*******************************************************************
- put a compressed nmb name into a buffer. return the length of the
- compressed name
- +
- + compressed names are really weird. The "compression" doubles the
- + size. The idea is that it also means that compressed names conform
- + to the doman name system. See RFC1002.
- ******************************************************************/
- static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
- {
- int ret,m;
- - char buf1[16];
- + fstring buf1;
- char *p;
-
- sprintf(buf1,"%-15.15s%c",name->name,name->name_type);
- @@ -217,31 +224,43 @@
- /*******************************************************************
- parse a dgram packet. Return False if the packet can't be parsed
- or is invalid for some reason, True otherwise
- +
- + this is documented in section 4.4.1 of RFC1002
- ******************************************************************/
- static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
- {
- int offset;
- + int flags;
-
- bzero((char *)dgram,sizeof(*dgram));
-
- if (length < 14) return(False);
-
- - dgram->header.res = RSVAL(inbuf,0);
- - dgram->header.id = RSVAL(inbuf,2);
- - putip((char *)&dgram->header.ip,inbuf+4);
- - dgram->header.port = RSVAL(inbuf,8);
- - dgram->header.length = RSVAL(inbuf,10);
- - dgram->header.res2 = RSVAL(inbuf,12);
- + dgram->header.msg_type = CVAL(inbuf,0);
- + flags = CVAL(inbuf,1);
- + dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
- + if (flags & 1) dgram->header.flags.more = True;
- + if (flags & 2) dgram->header.flags.first = True;
- + dgram->header.dgm_id = RSVAL(inbuf,2);
- + putip((char *)&dgram->header.source_ip,inbuf+4);
- + dgram->header.source_port = RSVAL(inbuf,8);
- + dgram->header.dgm_length = RSVAL(inbuf,10);
- + dgram->header.packet_offset = RSVAL(inbuf,12);
-
- offset = 14;
- - offset += parse_nmb_name(inbuf,offset,length,&dgram->header.source_name);
- - offset += parse_nmb_name(inbuf,offset,length,&dgram->header.dest_name);
- +
- + if (dgram->header.msg_type == 0x10 ||
- + dgram->header.msg_type == 0x11 ||
- + dgram->header.msg_type == 0x12) {
- + offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
- + offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
- + }
-
- - if (offset >= length || (length-offset > sizeof(dgram->smb_data)))
- + if (offset >= length || (length-offset > sizeof(dgram->data)))
- return(False);
-
- - dgram->smbsize = length-offset;
- - memcpy(dgram->smb_data,inbuf+offset,dgram->smbsize);
- + dgram->datasize = length-offset;
- + memcpy(dgram->data,inbuf+offset,dgram->datasize);
-
- return(True);
- }
- @@ -369,6 +388,9 @@
-
- num_good_receives++;
-
- + DEBUG(4,("%s received a packet of len %d from (%s) port %d\n",
- + timestring(),length,inet_ntoa(packet->ip),packet->port));
- +
- return(packet);
- }
-
- @@ -387,8 +409,8 @@
- sock_out.sin_port = htons( port );
- sock_out.sin_family = AF_INET;
-
- - DEBUG(3,("sending a packet of len %d to (%s) on port 137 of type DGRAM\n",
- - len,inet_ntoa(*ip)));
- + DEBUG(4,("%s sending a packet of len %d to (%s) on port %d\n",
- + timestring(),len,inet_ntoa(*ip),port));
-
- ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
- sizeof(sock_out)) >= 0);
- @@ -402,6 +424,59 @@
- return(ret);
- }
-
- +/*******************************************************************
- + build a dgram packet ready for sending
- +
- + XXXX This currently doesn't handle packets to big for one
- + datagram. It should split them and use the packet_offset, more and
- + first flags to handle the fragmentation. Yuck.
- + ******************************************************************/
- +static int build_dgram(char *buf,struct packet_struct *p)
- +{
- + struct dgram_packet *dgram = &p->packet.dgram;
- + unsigned char *ubuf = (unsigned char *)buf;
- + int offset=0;
- +
- + /* put in the header */
- + ubuf[0] = dgram->header.msg_type;
- + ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
- + if (dgram->header.flags.more) ubuf[1] |= 1;
- + if (dgram->header.flags.first) ubuf[1] |= 2;
- + RSSVAL(ubuf,2,dgram->header.dgm_id);
- + putip(ubuf+4,(char *)&dgram->header.source_ip);
- + RSSVAL(ubuf,8,dgram->header.source_port);
- + RSSVAL(ubuf,12,dgram->header.packet_offset);
- +
- + offset = 14;
- +
- + if (dgram->header.msg_type == 0x10 ||
- + dgram->header.msg_type == 0x11 ||
- + dgram->header.msg_type == 0x12) {
- + offset += put_nmb_name(ubuf,offset,&dgram->source_name);
- + offset += put_nmb_name(ubuf,offset,&dgram->dest_name);
- + }
- +
- + memcpy(ubuf+offset,dgram->data,dgram->datasize);
- + offset += dgram->datasize;
- +
- + /* automatically set the dgm_length */
- + dgram->header.dgm_length = offset;
- + RSSVAL(ubuf,10,dgram->header.dgm_length);
- +
- + return(offset);
- +}
- +
- +/*******************************************************************
- + build a nmb name
- + ******************************************************************/
- +void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope)
- +{
- + strcpy(n->name,name);
- + strupper(n->name);
- + n->name_type = type;
- + strcpy(n->scope,this_scope);
- +}
- +
-
- /*******************************************************************
- build a nmb packet ready for sending
- @@ -471,7 +546,7 @@
- break;
-
- case DGRAM_PACKET:
- - /* len = build_dgram(buf,p); */
- + len = build_dgram(buf,p);
- break;
- }
-
- @@ -500,5 +575,310 @@
- return(read_packet(fd,type));
-
- return(NULL);
- +}
- +
- +
- +/****************************************************************************
- +interpret a node status response
- +****************************************************************************/
- +static void interpret_node_status(char *p, char *master)
- +{
- + int level = master?3:0;
- + int numnames = CVAL(p,0);
- + DEBUG(level,("received %d names\n",numnames));
- +
- + p += 1;
- + while (numnames--)
- + {
- + char qname[17];
- + int type;
- + fstring flags="";
- + StrnCpy(qname,p,15);
- + type = CVAL(p,15);
- + p += 16;
- +
- + if (p[0] & 0x80) strcat(flags,"<GROUP> ");
- + if (p[0] & 0x60 == 0) strcat(flags,"B ");
- + if (p[0] & 0x60 == 1) strcat(flags,"P ");
- + if (p[0] & 0x60 == 2) strcat(flags,"M ");
- + if (p[0] & 0x60 == 3) strcat(flags,"_ ");
- + if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
- + if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
- + if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
- + if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
- +
- + if (master && type == 0x1d) {
- + StrnCpy(master,qname,15);
- + trim_string(master,NULL," ");
- + }
- +
- + DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags));
- + p+=2;
- + }
- + DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
- + IVAL(p,20),IVAL(p,24)));
- +}
- +
- +
- +/****************************************************************************
- + do a netbios name status to a host
- + **************************************************************************/
- +BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
- + struct in_addr to_ip,char *master,void (*fn)())
- +{
- + BOOL found=False;
- + int retries = 2;
- + int retry_time = 5000;
- + struct timeval tval;
- + struct packet_struct p;
- + struct packet_struct *p2;
- + struct nmb_packet *nmb = &p.packet.nmb;
- +
- + bzero((char *)&p,sizeof(p));
- +
- + if (!name_trn_id) name_trn_id = (time(NULL)%0x7FFF) + (getpid()%100);
- + name_trn_id = (name_trn_id+1) % 0x7FFF;
- +
- + nmb->header.name_trn_id = name_trn_id;
- + nmb->header.opcode = 0;
- + nmb->header.response = False;
- + nmb->header.nm_flags.bcast = False;
- + nmb->header.nm_flags.recursion_available = CanRecurse;
- + nmb->header.nm_flags.recursion_desired = recurse;
- + nmb->header.nm_flags.trunc = False;
- + nmb->header.nm_flags.authoritative = False;
- + nmb->header.rcode = 0;
- + nmb->header.qdcount = 1;
- + nmb->header.ancount = 0;
- + nmb->header.nscount = 0;
- + nmb->header.arcount = 0;
- +
- + make_nmb_name(&nmb->question.question_name,name,name_type,scope);
- +
- + nmb->question.question_type = 0x21;
- + nmb->question.question_class = 0x1;
- +
- + p.ip = to_ip;
- + p.port = NMB_PORT;
- + p.fd = fd;
- + p.timestamp = time(NULL);
- + p.packet_type = NMB_PACKET;
- +
- + GetTimeOfDay(&tval);
- +
- + if (!send_packet(&p))
- + return(False);
- +
- + retries--;
- +
- + while (1)
- + {
- + struct timeval tval2;
- + GetTimeOfDay(&tval2);
- + if (TvalDiff(&tval,&tval2) > retry_time) {
- + if (!retries) break;
- + if (!found && !send_packet(&p))
- + return False;
- + GetTimeOfDay(&tval);
- + retries--;
- + }
- +
- + if ((p2=receive_packet(fd,NMB_PACKET,90)))
- + {
- + struct nmb_packet *nmb2 = &p2->packet.nmb;
- + if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
- + !nmb2->header.response) {
- + /* its not for us - maybe deal with it later */
- + if (fn)
- + fn(p2);
- + else
- + free_packet(p2);
- + continue;
- + }
- +
- + if (nmb2->header.opcode != 0 ||
- + nmb2->header.nm_flags.bcast ||
- + nmb2->header.rcode ||
- + !nmb2->header.ancount) {
- + /* XXXX what do we do with this? could be a redirect, but
- + we'll discard it for the moment */
- + free_packet(p2);
- + continue;
- + }
- +
- + interpret_node_status(&nmb2->answers->rdata[0], master);
- + free_packet(p2);
- + return(True);
- + }
- + }
- +
- +
- + DEBUG(0,("No status response (this is not unusual)\n"));
- +
- + return(False);
- +}
- +
- +
- +/****************************************************************************
- + do a netbios name query to find someones IP
- + ****************************************************************************/
- +BOOL name_query(int fd,char *name,int name_type,
- + BOOL bcast,BOOL recurse,
- + struct in_addr to_ip, struct in_addr *ip,void (*fn)())
- +{
- + BOOL found=False;
- + int retries = 3;
- + int retry_time = bcast?250:5000;
- + struct timeval tval;
- + struct packet_struct p;
- + struct packet_struct *p2;
- + struct nmb_packet *nmb = &p.packet.nmb;
- +
- + bzero((char *)&p,sizeof(p));
- +
- + if (!name_trn_id) name_trn_id = (time(NULL)%0x7FFF) + (getpid()%100);
- + name_trn_id = (name_trn_id+1) % 0x7FFF;
- +
- + nmb->header.name_trn_id = name_trn_id;
- + nmb->header.opcode = 0;
- + nmb->header.response = False;
- + nmb->header.nm_flags.bcast = bcast;
- + nmb->header.nm_flags.recursion_available = CanRecurse;
- + nmb->header.nm_flags.recursion_desired = recurse;
- + nmb->header.nm_flags.trunc = False;
- + nmb->header.nm_flags.authoritative = False;
- + nmb->header.rcode = 0;
- + nmb->header.qdcount = 1;
- + nmb->header.ancount = 0;
- + nmb->header.nscount = 0;
- + nmb->header.arcount = 0;
- +
- + make_nmb_name(&nmb->question.question_name,name,name_type,scope);
- +
- + nmb->question.question_type = 0x20;
- + nmb->question.question_class = 0x1;
- +
- + p.ip = to_ip;
- + p.port = NMB_PORT;
- + p.fd = fd;
- + p.timestamp = time(NULL);
- + p.packet_type = NMB_PACKET;
- +
- + GetTimeOfDay(&tval);
- +
- + if (!send_packet(&p))
- + return(False);
- +
- + retries--;
- +
- + while (1)
- + {
- + struct timeval tval2;
- + GetTimeOfDay(&tval2);
- + if (TvalDiff(&tval,&tval2) > retry_time) {
- + if (!retries) break;
- + if (!found && !send_packet(&p))
- + return False;
- + GetTimeOfDay(&tval);
- + retries--;
- + }
- +
- + if ((p2=receive_packet(fd,NMB_PACKET,90)))
- + {
- + struct nmb_packet *nmb2 = &p2->packet.nmb;
- + if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
- + !nmb2->header.response) {
- + /* its not for us - maybe deal with it later (put it on the queue?) */
- + if (fn)
- + fn(p2);
- + else
- + free_packet(p2);
- + continue;
- + }
- +
- + if (nmb2->header.opcode != 0 ||
- + nmb2->header.nm_flags.bcast ||
- + nmb2->header.rcode ||
- + !nmb2->header.ancount) {
- + /* XXXX what do we do with this? could be a redirect, but
- + we'll discard it for the moment */
- + free_packet(p2);
- + continue;
- + }
- +
- + putip((char *)ip,&nmb2->answers->rdata[2]);
- + DEBUG(2,("Got a positive name query response from %s",
- + inet_ntoa(p2->ip)));
- + DEBUG(2,(" (%s)\n",inet_ntoa(*ip)));
- + found=True; retries=0;
- + free_packet(p2);
- + }
- + }
- +
- + return(found);
- +}
- +
- +
- +/****************************************************************************
- + construct and send a netbios DGRAM
- + **************************************************************************/
- +BOOL send_udp_dgram(int fd,char *buf,int len,
- + char *srcname,char *dstname,
- + int src_type,int dest_type,
- + struct in_addr dest_ip,
- + struct in_addr src_ip)
- +{
- + struct packet_struct p;
- + struct dgram_packet *dgram = &p.packet.dgram;
- + char *ptr,*p2;
- + char tmp[4];
- +
- + bzero((char *)&p,sizeof(p));
- +
- + dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
- + dgram->header.flags.node_type = M_NODE;
- + dgram->header.flags.first = True;
- + dgram->header.flags.more = False;
- + dgram->header.dgm_id = name_trn_id++;
- + dgram->header.source_ip = src_ip;
- + dgram->header.source_port = DGRAM_PORT;
- + dgram->header.dgm_length = 0; /* let build_dgram() handle this */
- + dgram->header.packet_offset = 0;
- +
- + make_nmb_name(&dgram->source_name,srcname,src_type,scope);
- + make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
- +
- + ptr = &dgram->data[0];
- +
- + /* now setup the smb part */
- + ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
- + memcpy(tmp,ptr,4);
- + set_message(ptr,17,17 + len,True);
- + memcpy(ptr,tmp,4);
- +
- + CVAL(ptr,smb_com) = SMBtrans;
- + SSVAL(ptr,smb_vwv1,len);
- + SSVAL(ptr,smb_vwv11,len);
- + SSVAL(ptr,smb_vwv12,86);
- + SSVAL(ptr,smb_vwv13,3);
- + SSVAL(ptr,smb_vwv14,1);
- + SSVAL(ptr,smb_vwv15,1);
- + SSVAL(ptr,smb_vwv16,2);
- + p2 = smb_buf(ptr);
- + strcpy(p2,"\\MAILSLOT\\BROWSE");
- + p2 = skip_string(p2,1);
- +
- + memcpy(p2,buf,len);
- + p2 += len;
- +
- + dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
- +
- + p.ip = dest_ip;
- + p.port = DGRAM_PORT;
- + p.fd = fd;
- + p.timestamp = time(NULL);
- + p.packet_type = DGRAM_PACKET;
- +
- + return(send_packet(&p));
- }
-
- diff -u -r --new-file last-version/source/nmblookup.c samba-1.9.14p4/source/nmblookup.c
- --- last-version/source/nmblookup.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.14p4/source/nmblookup.c Thu Nov 9 16:27:35 1995
- @@ -0,0 +1,213 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT client - used to lookup netbios names
- + Copyright (C) Andrew Tridgell 1994-1995
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- +*/
- +
- +#include "includes.h"
- +#include "nameserv.h"
- +
- +extern int DEBUGLEVEL;
- +
- +extern pstring scope;
- +
- +extern struct in_addr bcast_ip;
- +extern pstring myhostname;
- +
- +static BOOL got_bcast = False;
- +
- +int ServerFD=-1;
- +
- +/****************************************************************************
- + open the socket communication
- + **************************************************************************/
- +static BOOL open_sockets(void)
- +{
- + struct hostent *hp;
- +
- + /* get host info */
- + if ((hp = Get_Hostbyname(myhostname)) == 0)
- + {
- + DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
- + return False;
- + }
- +
- + ServerFD = open_socket_in(SOCK_DGRAM, 0,3);
- +
- + if (ServerFD == -1)
- + return(False);
- +
- + set_socket_options(ServerFD,"SO_BROADCAST");
- +
- + DEBUG(3, ("Socket opened.\n"));
- + return True;
- +};
- +
- +
- +/****************************************************************************
- + initialise connect, service and file structs
- +****************************************************************************/
- +static BOOL init_structs(void )
- +{
- + struct in_addr myip;
- +
- + if (!get_myname(myhostname,&myip))
- + return(False);
- +
- + /* Read the broadcast address from the interface */
- + {
- + struct in_addr ip0,ip2;
- +
- + ip0 = myip;
- +
- + if (!got_bcast) {
- + get_broadcast(&ip0,&bcast_ip,&ip2);
- +
- + DEBUG(2,("Using broadcast %s\n",inet_ntoa(bcast_ip)));
- + }
- + }
- +
- + return True;
- +}
- +
- +/****************************************************************************
- +usage on the program
- +****************************************************************************/
- +static void usage(void)
- +{
- + printf("Usage: nmblookup [-M] [-B bcast address] [-d debuglevel] name\n");
- + printf("Version %s\n",VERSION);
- + printf("\t-d debuglevel set the debuglevel\n");
- + printf("\t-B broadcast address the address to use for broadcasts\n");
- + printf("\t-M searches for a master browser\n");
- + printf("\t-S lookup node status as well\n");
- + printf("\n");
- +}
- +
- +
- +/****************************************************************************
- + main program
- +****************************************************************************/
- +int main(int argc,char *argv[])
- +{
- + int opt;
- + unsigned int lookup_type = 0x20;
- + pstring lookup;
- + extern FILE *dbf;
- + extern int optind;
- + extern char *optarg;
- + BOOL find_master=False;
- + BOOL find_status=False;
- + int i;
- +
- + DEBUGLEVEL = 1;
- + *lookup = 0;
- +
- + TimeInit();
- + charset_initialise();
- +
- + dbf = stdout;
- +
- + while ((opt = getopt(argc, argv, "p:d:B:i:SMh")) != EOF)
- + switch (opt)
- + {
- + case 'B':
- + {
- + unsigned long a = interpret_addr(optarg);
- + putip((char *)&bcast_ip,(char *)&a);
- + got_bcast = True;
- + }
- + break;
- + case 'i':
- + strcpy(scope,optarg);
- + strupper(scope);
- + break;
- + case 'M':
- + find_master = True;
- + break;
- + case 'S':
- + find_status = True;
- + break;
- + case 'd':
- + DEBUGLEVEL = atoi(optarg);
- + break;
- + case 'h':
- + usage();
- + exit(0);
- + break;
- + default:
- + usage();
- + exit(1);
- + }
- +
- + if (argc < 2) {
- + usage();
- + exit(1);
- + }
- +
- + init_structs();
- + if (!open_sockets()) return(1);
- +
- + DEBUG(1,("Sending queries to %s\n",inet_ntoa(bcast_ip)));
- +
- +
- + for (i=optind;i<argc;i++)
- + {
- + BOOL bcast = True;
- + int retries = 2;
- + char *p;
- + struct in_addr ip;
- +
- + strcpy(lookup,argv[i]);
- +
- + if (find_master) {
- + if (*lookup == '-') {
- + strcpy(lookup,"\01\02__MSBROWSE__\02");
- + lookup_type = 1;
- + } else {
- + lookup_type = 0x1d;
- + }
- + }
- +
- + p = strchr(lookup,'#');
- +
- + if (p) {
- + *p = 0;
- + sscanf(p+1,"%x",&lookup_type);
- + bcast = False;
- + retries = 1;
- + }
- +
- + if (name_query(ServerFD,lookup,lookup_type,bcast,True,
- + bcast_ip,&ip,NULL))
- + {
- + printf("%s %s\n",inet_ntoa(ip),lookup);
- + if (find_status)
- + {
- + printf("Looking up status of %s\n",inet_ntoa(ip));
- + name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL);
- + printf("\n");
- + }
- + } else {
- + printf("couldn't find name %s\n",lookup);
- + }
- + }
- +
- + return(0);
- +}
- diff -u -r --new-file last-version/source/password.c samba-1.9.14p4/source/password.c
- --- last-version/source/password.c Sun Nov 5 15:51:20 1995
- +++ samba-1.9.14p4/source/password.c Fri Nov 10 18:27:37 1995
- @@ -1231,9 +1231,10 @@
- standard_sub_basic(desthost);
- strupper(desthost);
-
- - {
- - unsigned long a = interpret_addr(desthost);
- - putip((char *)&dest_ip,(char *)&a);
- + dest_ip = *interpret_addr2(desthost);
- + if (zero_ip(dest_ip)) {
- + DEBUG(1,("Can't find password server\n"));
- + return(False);
- }
-
- if (memcmp(&dest_ip,&myip,sizeof(dest_ip)) == 0) {
- @@ -1241,7 +1242,7 @@
- return(False);
- }
-
- - password_client = open_socket_out(&dest_ip, port);
- + password_client = open_socket_out(SOCK_STREAM, &dest_ip, port);
- if (password_client < 0) {
- DEBUG(1,("%s not available\n",pserver));
- return(False);
- diff -u -r --new-file last-version/source/printing.c samba-1.9.14p4/source/printing.c
- --- last-version/source/printing.c Mon Nov 6 16:53:58 1995
- +++ samba-1.9.14p4/source/printing.c Fri Nov 10 10:41:24 1995
- @@ -25,8 +25,6 @@
- extern connection_struct Connections[];
- extern files_struct Files[];
-
- -/*BOOL lpq_cache_reset = False;*/
- -
- static BOOL * lpq_cache_reset=NULL;
-
- static int check_lpq_cache(int snum) {
- diff -u -r --new-file last-version/source/server.c samba-1.9.14p4/source/server.c
- --- last-version/source/server.c Tue Nov 7 18:24:54 1995
- +++ samba-1.9.14p4/source/server.c Fri Nov 10 18:28:21 1995
- @@ -3533,7 +3533,7 @@
- return(ERROR(ERRSRV,ERRaccess));
-
- /* load service specific parameters */
- - if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)))
- + if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
- return(ERROR(ERRSRV,ERRaccess));
-
- /* does this protocol need to be run as guest? */
- @@ -3739,9 +3739,8 @@
- #if PRIME_NMBD
- DEBUG(3,("priming nmbd\n"));
- {
- - struct in_addr ip;
- - uint32 a = interpret_addr("localhost");
- - putip((void *)&ip,(void *)&a);
- + struct in_addr ip = *interpret_addr2("localhost");
- + if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
- *OutBuffer = 0;
- send_one_packet(OutBuffer,1,&ip,137,SOCK_DGRAM);
- }
- diff -u -r --new-file last-version/source/smb.h samba-1.9.14p4/source/smb.h
- --- last-version/source/smb.h Tue Nov 7 18:24:53 1995
- +++ samba-1.9.14p4/source/smb.h Fri Nov 10 18:56:23 1995
- @@ -769,7 +769,7 @@
- BOOL mask_match( char *str, char *regexp, int case_sig, BOOL autoext);
- int dos_mode(int ,char *,struct stat *);
- char *timestring();
- -BOOL ip_equal(struct in_addr *ip1,struct in_addr *ip2);
- +BOOL ip_equal(struct in_addr ip1,struct in_addr ip2);
- BOOL send_one_packet(char *buf,int len,struct in_addr *ip,int port,int type);
- char *get_home_dir(char *);
- int set_filelen(int fd, long len);
- @@ -808,7 +808,6 @@
- BOOL set_filetime(char *fname,time_t mtime);
- char *dirname_dos(char *path,char *buf);
- BOOL get_myname(char *myname,struct in_addr *ip);
- -BOOL ip_equal(struct in_addr *ip1,struct in_addr *ip2);
- void expand_mask(char *Mask, BOOL);
- BOOL sane_unix_date(time_t unixdate);
- time_t start_of_month(void);
- @@ -816,7 +815,9 @@
- char *smb_fn_name(int cnum);
- void get_machine_info(void);
- int open_socket_in(int type, int port, int dlevel);
- -int open_socket_out(struct in_addr *addr, int port );
- +int open_socket_out(int type,struct in_addr *addr, int port );
- +struct in_addr *interpret_addr2(char *str);
- +BOOL zero_ip(struct in_addr ip);
- int read_max_udp(int fd,char *buffer,int bufsize,int maxtime);
- void log_in(char *buffer,int len);
- int interpret_protocol(char *str,int def);
- diff -u -r --new-file last-version/source/smbpasswd.c samba-1.9.14p4/source/smbpasswd.c
- --- last-version/source/smbpasswd.c Mon Nov 6 16:54:38 1995
- +++ samba-1.9.14p4/source/smbpasswd.c Fri Nov 10 10:41:23 1995
- @@ -22,11 +22,6 @@
- #include "includes.h"
- #include "des.h"
-
- -#ifdef SMBGETPASS
- -extern char *getsmbpass(char *);
- -#define getpass getsmbpass
- -#endif
- -
- /* Static buffers we will return. */
- static struct smb_passwd pw_buf;
- static pstring user_name;
- diff -u -r --new-file last-version/source/util.c samba-1.9.14p4/source/util.c
- --- last-version/source/util.c Tue Nov 7 18:24:45 1995
- +++ samba-1.9.14p4/source/util.c Fri Nov 10 19:38:26 1995
- @@ -1416,14 +1416,17 @@
- ********************************************************************/
- int ChDir(char *path)
- {
- + int res;
- static pstring LastDir="";
-
- if (strcsequal(path,".")) return(0);
-
- if (*path == '/' && strcsequal(LastDir,path)) return(0);
- DEBUG(3,("chdir to %s\n",path));
- - strcpy(LastDir,path);
- - return(sys_chdir(path));
- + res = sys_chdir(path);
- + if (!res)
- + strcpy(LastDir,path);
- + return(res);
- }
-
-
- @@ -1947,8 +1950,6 @@
-
- lastip = *(struct in_addr *) &sock.sa_data[2];
- lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
- - if (DEBUGLEVEL > 0)
- - DEBUG(3,("read %d bytes\n",ret));
-
- return(ret);
- }
- @@ -3481,15 +3482,12 @@
- /****************************************************************************
- true if two IP addresses are equal
- ****************************************************************************/
- -BOOL ip_equal(struct in_addr *ip1,struct in_addr *ip2)
- +BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
- {
- - char *p1=(char *)ip1;
- - char *p2=(char *)ip2;
- - int l = sizeof(*ip1);
- - while (l--)
- - if (*p1++ != *p2++)
- - return(False);
- - return(True);
- + unsigned long a1,a2;
- + putip((char *)&a1,(char *)&ip1);
- + putip((char *)&a2,(char *)&ip2);
- + return(a1 == a2);
- }
-
-
- @@ -3533,19 +3531,21 @@
- /* now we've got a socket - we need to bind it */
- if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
- {
- - if (port == 139 || port == 137)
- - DEBUG(dlevel,("bind failed on port %d\n",port));
- - close(res);
- + if (port) {
- + if (port == 139 || port == 137)
- + DEBUG(dlevel,("bind failed on port %d\n",port));
- + close(res);
-
- - if (dlevel > 0 && port < 1000)
- - port = 7999;
- + if (dlevel > 0 && port < 1000)
- + port = 7999;
-
- - if (port >= 1000 && port < 9000)
- - return(open_socket_in(type,port+1,dlevel));
- + if (port >= 1000 && port < 9000)
- + return(open_socket_in(type,port+1,dlevel));
- + }
-
- return(-1);
- }
- - DEBUG(1,("bind succeeded on port %d\n",port));
- + DEBUG(3,("bind succeeded on port %d\n",port));
-
- {
- int one=1;
- @@ -3557,17 +3557,19 @@
-
-
- /****************************************************************************
- -create an outgoing socket
- -****************************************************************************/
- -int open_socket_out(struct in_addr *addr, int port )
- + create an outgoing socket
- + **************************************************************************/
- +int open_socket_out(int type, struct in_addr *addr, int port )
- {
- struct sockaddr_in sock_out;
- int res;
-
- /* create a socket to write to */
- - res = socket(PF_INET, SOCK_STREAM, 0);
- + res = socket(PF_INET, type, 0);
- if (res == -1)
- { DEBUG(0,("socket error\n")); return -1; }
- +
- + if (type != SOCK_STREAM) return(res);
-
- bzero((char *)&sock_out,sizeof(sock_out));
- putip((char *)&sock_out.sin_addr,(char *)addr);
- @@ -3578,8 +3580,11 @@
- DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
-
- /* and connect it to the destination */
- - if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0)
- - { DEBUG(0,("connect error: %s\n",strerror(errno))); close(res); return -1; }
- + if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
- + DEBUG(0,("connect error: %s\n",strerror(errno)));
- + close(res);
- + return(-1);
- + }
-
- return res;
- }
- @@ -3634,21 +3639,47 @@
- struct hostent *hp;
- unsigned long res;
-
- - /* if it's in the form of an IP address then get the lib to interpret it */
- - if (isdigit(str[0]))
- - return(inet_addr(str));
- + if (strcmp(str,"0.0.0.0") == 0) return(0);
- + if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
-
- - /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
- - if ((hp = Get_Hostbyname(str)) == 0)
- - {
- + /* if it's in the form of an IP address then get the lib to interpret it */
- + if (isdigit(str[0])) {
- + res = inet_addr(str);
- + } else {
- + /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
- + if ((hp = Get_Hostbyname(str)) == 0) {
- DEBUG(0,("Get_Hostbyname: Unknown host. %s\n",str));
- return 0;
- }
- + putip((char *)&res,(char *)hp->h_addr);
- + }
- +
- + if (res == (unsigned long)-1) return(0);
-
- - putip((char *)&res,(char *)hp->h_addr);
- return(res);
- }
-
- +/*******************************************************************
- + a convenient addition to interpret_addr()
- + ******************************************************************/
- +struct in_addr *interpret_addr2(char *str)
- +{
- + static struct in_addr ret;
- + unsigned long a = interpret_addr(str);
- + putip((char *)&ret,(char *)&a);
- + return(&ret);
- +}
- +
- +/*******************************************************************
- + check if an IP is the 0.0.0.0
- + ******************************************************************/
- +BOOL zero_ip(struct in_addr ip)
- +{
- + unsigned long a;
- + putip((char *)&a,(char *)&ip);
- + return(a == 0);
- +}
- +
- #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
-
- /****************************************************************************
- @@ -4188,11 +4219,10 @@
-
- #ifdef REPLACE_RENAME
- /* Rename a file. (from libiberty in GNU binutils) */
- -
- int
- rename (zfrom, zto)
- - char *zfrom;
- - char *zto;
- + const char *zfrom;
- + const char *zto;
- {
- if (link (zfrom, zto) < 0)
- {
- @@ -4204,7 +4234,6 @@
- }
- return unlink (zfrom);
- }
- -
- #endif
-
- #if WRAP_MEMCPY
- diff -u -r --new-file last-version/source/version.h samba-1.9.14p4/source/version.h
- --- last-version/source/version.h Tue Nov 7 23:00:33 1995
- +++ samba-1.9.14p4/source/version.h Fri Nov 10 23:32:13 1995
- @@ -1 +1 @@
- -#define VERSION "1.9.14p3"
- +#define VERSION "1.9.14p4"
-